java - 无法使用 Spring boot 创建多个 Redis Sentinel Lettuce 连接
问题描述
所以目前的要求是这样的。
- 两个独立的 Redis Sentinel 服务器
- 一个用作数据库,一个用作缓存
问题仅在于哨兵
我能够为数据库和缓存创建配置。但是官方的 RedisSentinelConfiguration 类有以下硬编码的字段。 因此缓存连接也指向数据库连接。
以下是我的 redis 配置文件
@Configuration
public class RedisConfig {
@Value("${redis.type}")
String redisType;
@Value("${redis.commandTimeOut}")
Duration commandTimeOut;
@Bean(name = "jasyptStringEncryptor")
public StringEncryptor stringEncryptor() {
byte[] decodedBytes = Base64.getUrlDecoder().decode("aGVsbG8=");
PooledPBEStringEncryptor encryptor = new PooledPBEStringEncryptor();
encryptor.setPassword(new String(decodedBytes));
encryptor.setPoolSize(1);
encryptor.setProvider(new BouncyCastleProvider());
encryptor.setAlgorithm("PBEWITHSHA256AND256BITAES-CBC-BC");
encryptor.setKeyObtentionIterations(1000);
encryptor.setSaltGenerator(new org.jasypt.salt.RandomSaltGenerator());
return encryptor;
}
protected LettuceConnectionFactory clusterConnectionFactory(final RedisProperties redisProperties) {
RedisClusterConfiguration redisClusterConfiguration = new RedisClusterConfiguration(redisProperties.getCluster().getNodes());
redisClusterConfiguration.setPassword(redisProperties.getPassword());
final LettuceClientConfiguration.LettuceClientConfigurationBuilder lettuceClientConfigurationBuilder = LettuceClientConfiguration
.builder().commandTimeout(redisProperties.getTimeout());
if (redisProperties.isSsl()) {
lettuceClientConfigurationBuilder.useSsl();
}
final LettuceClientConfiguration lettuceClientConfiguration = LettuceClientConfiguration.builder().commandTimeout(commandTimeOut).build();
return new LettuceConnectionFactory(redisClusterConfiguration, lettuceClientConfiguration);
}
protected LettuceConnectionFactory standaloneConnectionFactory(final RedisProperties redisProperties) {
RedisStandaloneConfiguration redisStandaloneConfiguration = new RedisStandaloneConfiguration();
if (!DigitalApiUtils.isBlankStr(redisProperties.getPassword())) {
redisStandaloneConfiguration.setPassword(redisProperties.getPassword());
}
redisProperties.setPort(redisProperties.getPort());
redisStandaloneConfiguration.setHostName(redisProperties.getHost());
final LettuceClientConfiguration.LettuceClientConfigurationBuilder lettuceClientConfigurationBuilder = LettuceClientConfiguration
.builder().commandTimeout(redisProperties.getTimeout());
if (redisProperties.isSsl()) {
lettuceClientConfigurationBuilder.useSsl();
}
final LettuceClientConfiguration lettuceClientConfiguration = LettuceClientConfiguration.builder().commandTimeout(commandTimeOut).build();
return new LettuceConnectionFactory(redisStandaloneConfiguration, lettuceClientConfiguration);
}
protected LettuceConnectionFactory sentinelConnectionFactory(final RedisProperties redisProperties) {
RedisSentinelConfiguration sentinelConfig = new RedisSentinelConfiguration()
.master(redisProperties.getSentinel().getMaster());
redisProperties.getSentinel().getNodes().forEach(s -> sentinelConfig.sentinel(s, redisProperties.getPort()));
sentinelConfig.setPassword(redisProperties.getPassword());
sentinelConfig.setSentinelPassword(redisProperties.getPassword());
return new LettuceConnectionFactory(sentinelConfig, LettuceClientConfiguration.builder().commandTimeout(commandTimeOut).build());
}
@Bean
@Qualifier("redisConnectionFactory")
@Primary
protected LettuceConnectionFactory redisConnectionFactory(final RedisProperties redisProperties) {
LettuceConnectionFactory connectionFactory = null;
switch (redisType) {
case "STANDALONE":
connectionFactory = standaloneConnectionFactory(redisProperties);
break;
case "SENTINEL":
connectionFactory = sentinelConnectionFactory(redisProperties);
break;
case "CLUSTER":
connectionFactory = clusterConnectionFactory(redisProperties);
break;
default:
connectionFactory = standaloneConnectionFactory(redisProperties);
break;
}
return connectionFactory;
}
@Bean
@Qualifier("stringRedisTemplate")
@Primary
StringRedisTemplate stringRedisTemplate(final RedisProperties redisProperties) {
StringRedisTemplate stringRedisTemplate = new StringRedisTemplate(redisConnectionFactory(redisProperties));
stringRedisTemplate.setKeySerializer(new StringRedisSerializer());
stringRedisTemplate.setValueSerializer(new StringRedisSerializer());
return stringRedisTemplate;
}
}
@Configuration
public class RedisCacheConfig {
@Value("${redis.cache.type}")
String redisCacheType;
@Value("${redis.commandTimeOut}")
Duration commandTimeOut;
protected LettuceConnectionFactory clusterConnectionFactory(final RedisCacheProperties redisProperties) {
RedisClusterConfiguration redisClusterConfiguration = new RedisClusterConfiguration(redisProperties.getCluster().getNodes());
redisClusterConfiguration.setPassword(redisProperties.getPassword());
final LettuceClientConfiguration.LettuceClientConfigurationBuilder lettuceClientConfigurationBuilder = LettuceClientConfiguration
.builder().commandTimeout(redisProperties.getTimeout());
if (redisProperties.isSsl()) {
lettuceClientConfigurationBuilder.useSsl();
}
final LettuceClientConfiguration lettuceClientConfiguration = LettuceClientConfiguration.builder().commandTimeout(commandTimeOut).build();
return new LettuceConnectionFactory(redisClusterConfiguration, lettuceClientConfiguration);
}
protected LettuceConnectionFactory standaloneConnectionFactory(final RedisCacheProperties redisProperties) {
RedisStandaloneConfiguration redisStandaloneConfiguration = new RedisStandaloneConfiguration();
if(!DigitalApiUtils.isBlankStr(redisProperties.getPassword())){
redisStandaloneConfiguration.setHostName(redisProperties.getHost());
}
redisStandaloneConfiguration.setPassword(redisProperties.getPassword());
redisProperties.setPort(redisProperties.getPort());
final LettuceClientConfiguration.LettuceClientConfigurationBuilder lettuceClientConfigurationBuilder = LettuceClientConfiguration
.builder().commandTimeout(redisProperties.getTimeout());
if (redisProperties.isSsl()) {
lettuceClientConfigurationBuilder.useSsl();
}
final LettuceClientConfiguration lettuceClientConfiguration = LettuceClientConfiguration.builder().commandTimeout(commandTimeOut).build();
return new LettuceConnectionFactory(redisStandaloneConfiguration, lettuceClientConfiguration);
}
protected LettuceConnectionFactory sentinelConnectionFactory(final RedisCacheProperties redisProperties) {
RedisSentinelConfiguration sentinelConfig = new RedisSentinelConfiguration()
.master(redisProperties.getSentinel().getMaster());
redisProperties.getSentinel().getNodes().forEach(s -> sentinelConfig.sentinel(s, redisProperties.getPort()));
sentinelConfig.setPassword(redisProperties.getPassword());
sentinelConfig.setSentinelPassword(redisProperties.getPassword());
return new LettuceConnectionFactory(sentinelConfig, LettuceClientConfiguration.builder().commandTimeout(commandTimeOut).build());
}
@Bean
@Qualifier("redisCacheConnectionFactory")
protected LettuceConnectionFactory redisCacheConnectionFactory(final RedisCacheProperties redisProperties) {
LettuceConnectionFactory connectionFactory = null;
switch (redisCacheType) {
case "STANDALONE":
connectionFactory = standaloneConnectionFactory(redisProperties);
break;
case "SENTINEL":
connectionFactory = sentinelConnectionFactory(redisProperties);
break;
case "CLUSTER":
connectionFactory = clusterConnectionFactory(redisProperties);
break;
default:
connectionFactory = standaloneConnectionFactory(redisProperties);
break;
}
return connectionFactory;
}
@Bean
@Qualifier("redisCacheStringTemplate")
StringRedisTemplate redisCacheStringTemplate(final RedisCacheProperties redisProperties) {
StringRedisTemplate stringRedisTemplate = new StringRedisTemplate(redisCacheConnectionFactory(redisProperties));
stringRedisTemplate.setKeySerializer(new StringRedisSerializer());
stringRedisTemplate.setValueSerializer(new StringRedisSerializer());
return stringRedisTemplate;
}
@Bean
@Qualifier("cacheHashOperations")
public HashOperations cacheHashOperations(final RedisCacheProperties redisProperties) {
return redisCacheStringTemplate(redisProperties).opsForHash();
}
}
应用程序属性是
redis.type=SENTINEL
spring.redis.port=26379
spring.redis.sentinel.master=mymaster
spring.redis.sentinel.nodes={IP1}
spring.redis.password=password
spring.redis.timeout=PT20.345S
redis.commandTimeOut=3000ms
spring.cache.port=26379
spring.cache.sentinel.master=mymastercache
spring.cache.sentinel.nodes={IP2}
spring.cache.password=password
spring.cache.timeout=PT20.345S
redis.cache=3000ms
解决方案
推荐阅读
- python - Django update_or_create(获取部分)使用相关对象作为kwarg
- bash - 通过 xargs 将 sed 输出传送到 grep 的问题
- java - 如何在不使用 byte[] 的情况下在 json 文件中编写多个二进制文件?
- arrays - 理解 compactMap 和 flatMap 的问题
- scala - System.loadLibrary(“libName”)上的“java.library.path 中没有 libName”
- visual-studio - Visual Studio 2019 版本。高 CPU 使用率
- node.js - Node.js + 卡夫卡 + AWS
- java - 无法识别的字段,未标记为可忽略
- ios - 设计导航项右栏按钮,在传递数据时与另一个 VC 连接
- prebid.js - 如何修复 Prebid server-java 包构建错误