### 1.背景
> springboot使用redis单节点或者只使用哨兵、集群比较简单。yml配置即可,可以省去单独的连接池配置。实际项目中需要灵活切换单机或者哨兵模式,设计思路时如果配置了哨兵则连接池优先初始化哨兵工厂。反之使用单节点的默认redis配置即可。
### 2.pom.xml引入
org.springframework.boot
spring-boot-starter-data-redis
2.1.5.RELEASE
redis.clients
jedis
io.lettuce
lettuce-core
redis.clients
jedis
### 2.yml配置
> application.yml配置
```yaml
spring:
profiles:
active: dev
application:
name: redis-sentinel
redis:
sentinel:
master: ${redis.sentinel.master}
nodes: ${redis.sentinel.nodes}
password: ${redis.password}
timeout: ${redis.timeout}
jedis:
pool:
max-active: ${redis.jedis.pool.max-active}
max-idle: ${redis.jedis.pool.max-idle}
max-wait: ${redis.jedis.pool.max-wait}
testOnBorrow: ${redis.jedis.pool.testOnBorrow}
testOnReturn: ${redis.jedis.pool.testOnReturn}
database: ${redis.database}
#port: ${redis.port} #配置哨兵注释单节点信息
#host: ${redis.host}
```
> application-dev.yml配置
```yaml
#redis配置
redis:
sentinel:
master: mymaster
nodes: 127.0.0.1:26379 #多个哨兵用,分隔
password: 123456
timeout: 60000
jedis:
pool:
max-active: 400 #连接池最大连接数(使用负值表示没有限制)
max-idle: 20 #连接池中的最大空闲连接
max-wait: 1000 #连接池最大阻塞等待时间
testOnBorrow: false
testOnReturn: false
database: 0 #Redis数据库索引(默认为0)
port: 6379
host: 127.0.0.1
```
### 3.连接池配置
```java
@Configuration
@Slf4j
public class JedisConfig {
//redis哨兵中制定的mastername
@Value("${spring.redis.sentinel.master:false}")
private String sentinelMaster;
//redis哨兵节点
@Value("${spring.redis.sentinel.nodes: false}")
private String sentinelNodes;
/**
*redis哨兵配置
*/
@Bean
@ConditionalOnProperty(prefix="spring.redis.sentinel", name={"nodes", "master"})
public RedisSentinelConfiguration redisSentinelConfiguration() {
RedisSentinelConfiguration configuration = new RedisSentinelConfiguration();
String[] nodes = sentinelNodes.split(",");
for(String node:nodes) {
String[] item = node.split(":");
String ip = item[0];
String port = item[1];
configuration.addSentinel(new RedisNode(ip, Integer.parseInt(port)));
}
configuration.setMaster(sentinelMaster);
log.info("=========== RedisSentinelConfiguration init");
return configuration;
}
/**
*初始化连接工厂
*/
@ConfigurationProperties(prefix="spring.redis")
@Bean
public JedisConnectionFactory getJedisConnectionFactory(@org.springframework.lang.Nullable RedisSentinelConfiguration sentinelConfig,JedisPoolConfig config) {
//使用构造方法注入哨兵配置
JedisConnectionFactory factory = null;
if (sentinelConfig == null){
factory = new JedisConnectionFactory(config);
log.info("=========== JedisConnectionFactory init");
} else {
factory = new JedisConnectionFactory(sentinelConfig,config);
log.info("=========== JedisConnectionFactory from RedisSentinelConfiguration init");
}
return factory;
}
/**
* redis连接池配置信息
*/
@Bean
@ConfigurationProperties(prefix="spring.redis.jedis.pool")
public JedisPoolConfig redisPoolConfig() {
JedisPoolConfig config = new JedisPoolConfig();
config.setTestOnBorrow(true);
return config;
}
}
```
### 4.RedisTemplate序列化配置
```java
@Configuration
@Slf4j
public class RedisConfig {
/**
* redis模板,存储关键字是字符串,值jackson2JsonRedisSerializer是序列化后的值
*/
@Bean
public RedisTemplate redisTemplate(RedisConnectionFactory connectionFactory, Jackson2JsonRedisSerializer jackson2JsonRedisSerializer) {
RedisTemplate redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(connectionFactory);
//使用Jackson2JsonRedisSerializer来序列化和反序列化redis的value值(默认使用JDK的序列化方式)
//使用StringRedisSerializer来序列化和反序列化redis的key值
RedisSerializer redisSerializer = new StringRedisSerializer();
//key
redisTemplate.setKeySerializer(redisSerializer);
redisTemplate.setHashKeySerializer(redisSerializer);
//value
redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);
redisTemplate.afterPropertiesSet();
log.info("RedisTemplate Bean init success" );
return redisTemplate;
}
/**
* Jackson2JsonRedisSerializer来序列化和反序列化
* @return
*/
@Bean
public Jackson2JsonRedisSerializer getJackson2JsonRedisSerializer() {
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer
SpringBoot集成Redis单节点和哨兵