springboot2.x集成redis。redis节点故障,集群状态ok的情况下,程序使用redisTemplate操作redis一直报错:
Redis command timed out; nested exception is io.lettuce.core.RedisCommandTimeoutException: Command timed out after 1 minute(s)
代码如下:
RedisService.java
package com.harara;
import com.harara.RedisConfig;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Primary;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Component;
import java.io.Serializable;
/**
* @author: harara
* @date: 2020-9-07 18:23
* @description:
* @version: 1.0
*/
@Slf4j
@Component
public class RedisService {
@Autowired
private RedisTemplate redisTemplate;
@Autowired
private RedisConfig redisConfig;
/**
* 更新redisTemplate :处理集群宕机恢复后程序不恢复问题
* 重新初始化redisTemplate的连接工厂connectionFactory
*/
private RedisTemplate refreshRedisTemplate(){
LettuceConnectionFactory connectionFactory = redisConfig.connectionFactory();
connectionFactory.afterPropertiesSet();
redisTemplate.setConnectionFactory(connectionFactory);
return redisTemplate;
}
/**
* @param key
* @return
*/
public Object get(final String key){
ValueOperations<Serializable, Object> operations = null;
try {
operations= redisTemplate.opsForValue();
return operations.get(key);
}catch (Exception e){
log.error("redis操作string get出现异常:{}",e.getMessage());
operations = refreshRedisTemplate().opsForValue();
return operations.get(key);
}
}
}
RedisConfig.java
package com.harara;
import cn.hutool.core.util.StrUtil;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.core.env.MapPropertySource;
import org.springframework.data.redis.connection.RedisClusterConfiguration;
import org.springframework.data.redis.connection.RedisStandaloneConfiguration;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import java.util.HashMap;
import java.util.Map;
/**
* redis 配置类
* @author harara
* @date 2020/9/7 11:34
*
*/
@Configuration
@Order(value = 1)
public class RedisConfig {
//redis连接的database
@Value("${spring.redis.database:0}")
private int database;
//集群节点配置
@Value("${spring.redis.cluster.nodes:#{null}}")
private String nodes;
//集群最大连接转移数
@Value("${spring.redis.cluster.max-redirects:3}")
private int maxRedirects;
//单节点情况下redis的ip
@Value("${spring.redis.host:#{null}}")
private String host;
//单节点情况下redis的端口
@Value("${spring.redis.port:#{null}}")
private Integer port;
//redis的连接密码
@Value("${spring.redis.password:#{null}}")
private String password;
/**
* 创建连接工厂LettuceConnectionFactory
* @return
*/
public LettuceConnectionFactory connectionFactory() {
Map<String, Object> source = new HashMap<String, Object>();
RedisClusterConfiguration redisClusterConfiguration;
RedisStandaloneConfiguration redisStandaloneConfiguration;
//集群模式
if(nodes !=null){
source.put("spring.redis.cluster.nodes", nodes);
source.put("spring.redis.cluster.max-redirects", maxRedirects);
redisClusterConfiguration = new RedisClusterConfiguration(new MapPropertySource("RedisClusterConfiguration", source));
if(!StrUtil.isEmpty(password)){
redisClusterConfiguration.setPassword(password);
}
//创建连接工厂
LettuceConnectionFactory lettuceConnectionFactory = new
LettuceConnectionFactory(redisClusterConfiguration);
return lettuceConnectionFactory;
}else{
//单机模式
redisStandaloneConfiguration = new RedisStandaloneConfiguration(host,port);
redisStandaloneConfiguration.setDatabase(database);
if(!StrUtil.isEmpty(password)){
redisStandaloneConfiguration.setPassword(password);
}
//创建连接工厂
LettuceConnectionFactory lettuceConnectionFactory = new
LettuceConnectionFactory(redisStandaloneConfiguration);
return lettuceConnectionFactory;
}
}
}