最近在使用SpringCloudGataWay搭建一个路由项目,想着用Reids做一层缓存,而且也想图省事直接使用springcloud自带的限流器,它的限流器很简单就是基于redis实现的令牌桶模式 很方便
但可怕的事发生了,他居然用的ReactiveRedis也就是异步实现的一套redis东西,和我们常用的data-redis和jedis这些东西完全不兼容也就是这个东西
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis-reactive</artifactId>
</dependency>
本质上它是实现一套异步非阻塞交互的东西,很好用 就是有点难理解,项目中还有很多需要用到Redis的地方,学习成本和可靠性是我需要考虑的。
所以我只需要限流器使用现成的就可以了,其他的我还是需要按照传统redis的方式去处理,发现他除了网络方面有改写其他和redis很像,于是写了一段RedisConfig。。。果然就是各种报错。发现除了template返回很多异步的处理,连连接工厂也换成了lettuce这当然是要各种报错了。于是查了下lettuce,可以兼容处理成只需要连接的改变即可。
```java
@Configuration
public class RedisConfig {
@Value(“${spring.redis.database}”)
private int database;
@Value("${spring.redis.host}")
private String host;
@Value("${spring.redis.password:#{null}}")
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;
/**
* 缓存有效期
*/
private Duration entryTtl = Duration.ofHours(24L);
/**
* 连接超时
*/
private Duration connectTimeout = Duration.ofSeconds(15L);
/**
* 读取超时
*/
private Duration readTimeout = Duration.ofSeconds(30L);
@Bean
LettuceConnectionFactory lettuceConnectionFactory(GenericObjectPoolConfig genericObjectPoolConfig) {
// 单机版配置
RedisStandaloneConfiguration redisStandaloneConfiguration = new RedisStandaloneConfiguration();
redisStandaloneConfiguration.setDatabase(database);
redisStandaloneConfiguration.setHostName(host);
redisStandaloneConfiguration.setPort(port);
redisStandaloneConfiguration.setPassword(RedisPassword.of(password));
// 集群版配置
// RedisClusterConfiguration redisClusterConfiguration = new RedisClusterConfiguration();
// String[] serverArray = clusterNodes.split(“,”);
// Set
// for (String ipPort : serverArray) {
// String[] ipAndPort = ipPort.split(“:”);
// nodes.add(new RedisNode(ipAndPort[0].trim(), Integer.valueOf(ipAndPort[1])));
// }
// redisClusterConfiguration.setPassword(RedisPassword.of(password));
// redisClusterConfiguration.setClusterNodes(nodes);
// redisClusterConfiguration.setMaxRedirects(maxRedirects);
LettuceClientConfiguration clientConfig = LettucePoolingClientConfiguration.builder()
.commandTimeout(Duration.ofMillis(timeout))
.poolConfig(genericObjectPoolConfig)
.build();
LettuceConnectionFactory factory = new LettuceConnectionFactory(redisStandaloneConfiguration, clientConfig);
return factory;
}
/**
* GenericObjectPoolConfig 连接池配置
*
* @return
*/
@Bean
public GenericObjectPoolConfig genericObjectPoolConfig() {
GenericObjectPoolConfig genericObjectPoolConfig = new GenericObjectPoolConfig();
genericObjectPoolConfig.setMaxIdle(maxIdle);
genericObjectPoolConfig.setMinIdle(minIdle);
genericObjectPoolConfig.setMaxTotal(maxActive);
genericObjectPoolConfig.setMaxWaitMillis(maxWait);
return genericObjectPoolConfig;
}
/**
* 实例化 RedisTemplate 对象
*
* @return
*/
@Bean
public RedisTemplate<String, Object> functionDomainRedisTemplate() {
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
initDomainRedisTemplate(redisTemplate, lettuceConnectionFactory(genericObjectPoolConfig()));
return redisTemplate;
}
/**
* 设置数据存入 redis 的序列化方式
*
* @param redisTemplate
* @param factory
*/
private void initDomainRedisTemplate(RedisTemplate<String, Object> redisTemplate, RedisConnectionFactory factory) {
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setValueSerializer(new KryoRedisSerializer<>(Object.class));
redisTemplate.setHashKeySerializer(new StringRedisSerializer());
redisTemplate.setHashValueSerializer(new KryoRedisSerializer<>(Object.class));
ParserConfig.getGlobalInstance().setAutoTypeSupport(true);
redisTemplate.setConnectionFactory(factory);
}
/**
* 实例化 HashOperations 对象,可以使用 Hash 类型操作
*
* @param redisTemplate
* @return
*/
@Bean
public HashOperations<String, String, Object> hashOperations(RedisTemplate<String, Object> redisTemplate) {
return redisTemplate.opsForHash();
}
/**
* 实例化 ValueOperations 对象,可以使用 String 操作
*
* @param redisTemplate
* @return
*/
@Bean
public ValueOperations<String, Object> valueOperations(RedisTemplate<String, Object> redisTemplate) {
return redisTemplate.opsForValue();
}
/**
* 实例化 ListOperations 对象,可以使用 List 操作
*
* @param redisTemplate
* @return
*/
@Bean
public ListOperations<String, Object> listOperations(RedisTemplate<String, Object> redisTemplate) {
return redisTemplate.opsForList();
}
/**
* 实例化 SetOperations 对象,可以使用 Set 操作
*
* @param redisTemplate
* @return
*/
@Bean
public SetOperations<String, Object> setOperations(RedisTemplate<String, Object> redisTemplate) {
return redisTemplate.opsForSet();
}
/**
* 实例化 ZSetOperations 对象,可以使用 ZSet 操作
*
* @param redisTemplate
* @return
*/
@Bean
public ZSetOperations<String, Object> zSetOperations(RedisTemplate<String, Object> redisTemplate) {
return redisTemplate.opsForZSet();
}
}
```