在SpringBoot1.x版本中,springboot默认使用集成jedis,在SpringBoot2.x版本中,SpringBoot默认集成lettuce。
1. Jedis使用直连方式连接Redis Server,在多线程环境下存在线程安全问题,需要增加连接池创建Jedis客户端多实例线程安全问题,基于传统I/O模式,是阻塞式传输!
2. Lettuce的连接是基于netty,在多线程环境下不存在线程安全问题,这个连接实例当然也是可伸缩的设计,也可以增加多实例连接,netty本身就基于NIO,从而提供了异步和同步数据访问方式,用于构建非阻塞的反应性应用程序。
<properties>
<spring-boot.version>2.3.4.RELEASEspring-boot.version>
<commons-pool.version>2.5.0commons-pool.version>
properties>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-data-redisartifactId>
<version>${spring-boot.version}version>
dependency>
<dependency>
<groupId>org.apache.commonsgroupId>
<artifactId>commons-pool2artifactId>
<version>${commons-pool.version}version>
dependency>
#yaml配置
spring:
redis:
database: 0
cluster:
nodes: 127.0.0.1:7001,127.0.0.1:7002,127.0.0.1:7003,127.0.0.1:7004,127.0.0.1:7005,127.0.0.1:7006 #集群节点
password: xxxx #密码
lettuce:
pool:
max-active: 10 #连接池最大连接数
max-idle: 8 #连接池中最大空闲连接数
max-wait: -1ms #连接池最大等待阻塞时间
min-idle: 0 #连接池中最小空闲数
timeout: 5000 #访问超时时间
@Configuration
public class RedisConfig {
@Bean
RedisTemplate<String, Serializable> redisTemplate(LettuceConnectionFactory redisConnectionFactory) {
RedisTemplate<String, Serializable> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(redisConnectionFactory);
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setHashKeySerializer(new StringRedisSerializer());
redisTemplate.afterPropertiesSet();
return redisTemplate;
}
@Bean
public CacheManager cacheManager(LettuceConnectionFactory factory) {
// 配置序列化
RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig();
RedisCacheConfiguration redisCacheConfiguration = config.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer())).serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer()));
return RedisCacheManager.builder(factory).cacheDefaults(redisCacheConfiguration).build();
}
}
<properties>
<spring-boot.version>2.3.4.RELEASEspring-boot.version>
<jedis.version>3.3.0jedis.version>
properties>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-data-redisartifactId>
<version>${spring-boot.version}version>
<exclusions>
<exclusion>
<groupId>io.lettucegroupId>
<artifactId>lettuce-coreartifactId>
exclusion>
exclusions>
dependency>
<dependency>
<groupId>redis.clientsgroupId>
<artifactId>jedisartifactId>
<version>${jedis.version}version>
dependency>
注:这里有一个比较坑的地方,导入的Jedis版本必须要和springboot版本兼容,需要点入spring-boot-starter-data-redis的pom文件查看spring-data-redis,然后继续点击spring-data-redis查看对应jedis版本
第三步:就可以查看到当前springboot对应哪一个jedis版本,然后在自己的pom中引入和这个redis对应的版本。
#yaml配置
spring:
redis:
database: 0
cluster:
nodes: 127.0.0.1:7001,127.0.0.1:7002,127.0.0.1:7003,127.0.0.1:7004,127.0.0.1:7005,127.0.0.1:7006 #集群节点
password: xxxx #密码
jedis:
pool:
max-active: 10 #连接池最大连接数
max-idle: 8 #连接池中最大空闲连接数
max-wait: -1 #连接池最大等待阻塞时间
min-idle: 0 #连接池中最小空闲数
timeout: 5000 #访问超时时间
@Value("${spring.redis.cluster.nodes}")
private String host;
@Value("${spring.redis.password}")
private String password;
@Value("${spring.redis.timeout}")
private int connectionTimeout;
@Value("${spring.redis.jedis.pool.max-active}")
private int maxTotal;
@Value("${spring.redis.jedis.pool.min-idle}")
private int minIdle;
@Value("${spring.redis.jedis.pool.max-idle}")
private int maxIdle;
@Value("${spring.redis.jedis.pool.max-wait}")
private int maxWaitMillis;
@Bean
public RedisClusterConfiguration redisClusterConfiguration() {
RedisClusterConfiguration redisClusterConfiguration = new RedisClusterConfiguration();
String[] hosts = host.split(",");
Set<RedisNode> nodeList = new HashSet<RedisNode>();
for (String hostAndPort : hosts) {
String[] hostOrPort = hostAndPort.split(":");
nodeList.add(new RedisNode(hostOrPort[0], Integer.parseInt(hostOrPort[1])));
}
redisClusterConfiguration.setClusterNodes(nodeList);
// redisClusterConfiguration.setMaxRedirects();
return redisClusterConfiguration;
}
@Bean
public JedisPoolConfig jedisPoolConfig() {
JedisPoolConfig poolConfig = new JedisPoolConfig();
poolConfig.setMaxIdle(this.maxIdle);
poolConfig.setMinIdle(this.minIdle);
poolConfig.setTestOnCreate(true);
poolConfig.setTestOnBorrow(true);
poolConfig.setTestOnReturn(true);
poolConfig.setTestWhileIdle(true);
return poolConfig;
}
@Bean("myJedisConnectionFactory")
public JedisConnectionFactory jedisConnectionFactory(RedisClusterConfiguration redisClusterConfiguration,
JedisPoolConfig jedisPoolConfig) {
JedisConnectionFactory jedisConnectionFactory = new JedisConnectionFactory(
redisClusterConfiguration, jedisPoolConfig);
jedisConnectionFactory.setPassword(password);
return jedisConnectionFactory;
}
@Bean
RedisTemplate<String, Serializable> redisTemplate(@Qualifier("myJedisConnectionFactory")JedisConnectionFactory jedisConnectionFactory) {
RedisTemplate<String, Serializable> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(jedisConnectionFactory);
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
// 设置值(value)的序列化采用Jackson2JsonRedisSerializer。
redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
// 设置键(key)的序列化采用StringRedisSerializer。
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setHashKeySerializer(new StringRedisSerializer());
redisTemplate.afterPropertiesSet();
return redisTemplate;
}
@Bean
public CacheManager cacheManager(@Qualifier("myJedisConnectionFactory")JedisConnectionFactory jedisConnectionFactory) {
RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig();
RedisCacheConfiguration redisCacheConfiguration = config
.serializeKeysWith(
RedisSerializationContext.SerializationPair
.fromSerializer(new StringRedisSerializer()))
.serializeValuesWith(
RedisSerializationContext.SerializationPair
.fromSerializer(new GenericJackson2JsonRedisSerializer()));
return RedisCacheManager.builder(jeddisConnectionFactory)
.cacheDefaults(redisCacheConfiguration).build();
}
项目中直接注入RedisTemplate就可以使用,具体网上步骤很多,在这里不展开来说。
本文只记录相关配置,后续有时间会做源码分析和大家分享,文中如有错误之处,欢迎指出。