背景:项目redis由集群改为哨兵模式,漏洞扫描未授权访问漏洞(CNVD-2019-21763),要求对redis哨兵也设置密码,redisson依赖版本为3.11.5 spring-boot版本为2.1.13。
redisson依赖升级
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson-spring-boot-starter</artifactId>
<version>3.15.6</version>
<exclusions>
<exclusion>
<groupId>org.redisson</groupId>
<artifactId>redisson-spring-data-24</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson-spring-data-21</artifactId>
<version>3.15.6</version>
</dependency>
说明:3.11.5版本不支持设置哨兵密码,也就是SentinelPassword,需要升级redisson版本,为什么排除redisson-spring-data-24,高版本redisson会排除jedis以及lettuce,如果不排除并重新引入的话启动会报错,报错如下:java.lang.NoClassDefFoundError:org/springframework/data/redis/connection/RedisStreamCommands
2.1.X版本支持的是redisson-spring-data-21,所以排除springboot2.3的支持,引入2.1的支持。
配置:
spring.redis.database=0
spring.redis.password=HcicloudRedis2000
spring.redis.sentinel.master=mymaster
spring.redis.sentinel.nodes=ip:port
spring.redis.jedis.pool.max-idle=200
spring.redis.jedis.pool.min-idle=10
spring.redis.jedis.pool.max-active=200
spring.redis.jedis.pool.max-wait=10000ms
spring.redis.jedis.pool.ping-rate=30000
spring.redis.jedis.pool.timeout=10000
config:
@Configuration
@ConfigurationProperties
@Data
public class RedissonConfig {
@Value("${spring.redis.sentinel.nodes:}")
private String nodes;
@Value("${spring.redis.sentinel.master:}")
private String master;
@Value("${spring.redis.jedis.pool.timeout}")
private int timeout;
@Value("${spring.redis.password}")
private String password;
@Value("${spring.redis.database}")
private int database;
@Value("${spring.redis.jedis.pool.max-idle}")
private int maxPool;
@Value("${spring.redis.jedis.pool.min-idle}")
private int minPool;
@Value("${spring.redis.jedis.pool.max-active}")
private int maxActive;
@Value("${spring.redis.jedis.pool.ping-rate}")
private int pingRate;
@Bean
@ConditionalOnMissingBean
RedissonClient redissonSentinel(){
Config config = new Config();
String[] nodesStr = nodes.split(",");
List<String> nodeList = new ArrayList<>(nodesStr.length);
Arrays.stream(nodesStr).forEach((index)->nodeList.add(index.startsWith("redis://")?index:"redis://"+index));
SentinelServersConfig sentinelConfig = config.useSentinelServers()
.addSentinelAddress(nodeList.toArray(new String[0]))
.setCheckSentinelsList(false)
.setPingConnectionInterval(pingRate)
.setMasterName(master)
.setDatabase(database)
.setReadMode(ReadMode.SLAVE)
.setMasterConnectionMinimumIdleSize(minPool)
.setSlaveConnectionMinimumIdleSize(minPool)
.setMasterConnectionPoolSize(maxPool)
.setSlaveConnectionPoolSize(maxPool)
.setTimeout(timeout);
if(StringUtils.isNotEmpty(password)){
sentinelConfig.setPassword(password).setSentinelPassword(password); //哨兵和master的密码在配置中保持了一致,请根据项目实际情况配置
}
return Redisson.create(config);
}
}