解决springboot2.x集成redis节点故障redisTemplate报错redis Command timed out

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)

解决方案:捕获redisTemplate操作的异常,然后重新初始化redisTemplate的连接工厂connectionFactory

代码如下:

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;
        }
    }
    
}
原文地址:https://www.cnblogs.com/kiko2014551511/p/13716718.html