lettuce介绍: Lettuce是一个高性能基于Java编写的Redis驱动框架,底层集成了Project Reactor提供自然的反应式编程,通讯框架集成了Netty使用了非阻塞IO,5.x版本以后融合了JDK1.8的异步编程特性,在保证高性能的同时提供了十分丰富易用的API。 在高版本的spring-data-redis中都整合了lettuce。
Maven: <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency>
Lettuce配置: /** * Lettuce客户端配置 */ @Configuration public class LettuceRedisConfig { @Value("${spring.redis.database}") private int database; @Value("${spring.redis.host}") private String host; @Value("${spring.redis.password}") private String password; @Value("${spring.redis.port}") private int port; @Value("${spring.redis.timeout}") private long timeout; @Value("${spring.redis.lettuce.pool.max-idle}") private int maxIdle; @Value("${spring.redis.lettuce.pool.min-idle}") private int minIdle; @Value("${spring.redis.lettuce.pool.max-active}") private int maxActive; @Value("${spring.redis.lettuce.pool.max-wait}") private long maxWait; /** * 单机版配置 */ @Bean LettuceConnectionFactory lettuceConnectionFactory(GenericObjectPoolConfig genericObjectPoolConfig) { RedisStandaloneConfiguration redisStandaloneConfiguration = new RedisStandaloneConfiguration(); redisStandaloneConfiguration.setDatabase(database); redisStandaloneConfiguration.setHostName(host); redisStandaloneConfiguration.setPort(port); redisStandaloneConfiguration.setPassword(RedisPassword.of(password)); LettuceClientConfiguration clientConfig = LettucePoolingClientConfiguration.builder() .commandTimeout(Duration.ofMillis(timeout)) .poolConfig(genericObjectPoolConfig) .build(); return new LettuceConnectionFactory(redisStandaloneConfiguration,clientConfig); } /** * GenericObjectPoolConfig 连接池配置 */ @Bean public GenericObjectPoolConfig genericObjectPoolConfig() { GenericObjectPoolConfig genericObjectPoolConfig = new GenericObjectPoolConfig(); genericObjectPoolConfig.setMaxIdle(maxIdle); genericObjectPoolConfig.setMinIdle(minIdle); genericObjectPoolConfig.setMaxTotal(maxActive); genericObjectPoolConfig.setMaxWaitMillis(maxWait); return genericObjectPoolConfig; } }
properties配置:
#redis redis.token.expiretime= 100 spring.redis.host=127.0.0.1 spring.redis.port=6379 spring.redis.password= spring.redis.database=1 spring.redis.timeout=10000 spring.redis.lettuce.pool.max-active=8 spring.redis.lettuce.pool.max-idle=8 spring.redis.lettuce.pool.min-idle=0 spring.redis.lettuce.pool.max-wait=-1
/** * redis配置 */
@Slf4j @EnableCaching @Configuration public class RedisConfig extends CachingConfigurerSupport { /** * RedisTemplate配置 */ @Bean public RedisTemplate<String, Object> redisTemplate(LettuceConnectionFactory lettuceConnectionFactory) { //设置序列化 Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class); ObjectMapper om = new ObjectMapper(); om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); om.activateDefaultTyping(LaissezFaireSubTypeValidator.instance,ObjectMapper.DefaultTyping.NON_FINAL); jackson2JsonRedisSerializer.setObjectMapper(om); // 配置redisTemplate RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>(); redisTemplate.setConnectionFactory(lettuceConnectionFactory); RedisSerializer<String> stringSerializer = new StringRedisSerializer(); // key序列化 redisTemplate.setKeySerializer(stringSerializer); // value序列化 redisTemplate.setValueSerializer(jackson2JsonRedisSerializer); // Hash key序列化 redisTemplate.setHashKeySerializer(stringSerializer); // Hash value序列化 redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer); redisTemplate.afterPropertiesSet(); return redisTemplate; } /** * 缓存管理器 */ @Bean public CacheManager cacheManager(LettuceConnectionFactory lettuceConnectionFactory) { // 关键点,spring cache的注解使用的序列化都从这来,没有这个配置的话使用的jdk自己的序列化 RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig() .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(keySerializer())) .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(valueSerializer())) .disableCachingNullValues(); RedisCacheManager.RedisCacheManagerBuilder builder = RedisCacheManager.RedisCacheManagerBuilder .fromConnectionFactory(lettuceConnectionFactory) .cacheDefaults(config) .transactionAware(); return builder.build(); } /** * 异常处理,当Redis发生异常时,打印日志,但是程序正常走 */ @Override @Bean public CacheErrorHandler errorHandler() { log.info("初始化 -> [{}]", "Redis CacheErrorHandler"); return new CacheErrorHandler() { @Override public void handleCacheGetError(RuntimeException e, Cache cache, Object key) { log.error("Redis occur handleCacheGetError:key -> [{}]", key, e); } @Override public void handleCachePutError(RuntimeException e, Cache cache, Object key, Object value) { log.error("Redis occur handleCachePutError:key -> [{}];value -> [{}]", key, value, e); } @Override public void handleCacheEvictError(RuntimeException e, Cache cache, Object key) { log.error("Redis occur handleCacheEvictError:key -> [{}]", key, e); } @Override public void handleCacheClearError(RuntimeException e, Cache cache) { log.error("Redis occur handleCacheClearError:", e); } }; } /** * key 序列化 */ private RedisSerializer<String> keySerializer() { return new StringRedisSerializer(); } /** * value 序列化 */ private RedisSerializer<Object> valueSerializer() { Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class); ObjectMapper om = new ObjectMapper(); om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); om.activateDefaultTyping(LaissezFaireSubTypeValidator.instance,ObjectMapper.DefaultTyping.NON_FINAL); om.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); jackson2JsonRedisSerializer.setObjectMapper(om); return jackson2JsonRedisSerializer; } /** * json数据转换类设置 */ private ObjectMapper setObjectMapper() { ObjectMapper om = new ObjectMapper(); om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL); return om; } }