• 解决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;
            }
        }
        
    }
  • 相关阅读:
    Redis --> Redis架构设计
    Redis --> 为redis分配新的端口
    大数据 --> CAP原理和最终一致性
    大数据 --> 一致性Hash算法
    大数据 --> 分布式服务框架Zookeeper
    网络通信 --> Linux 五种IO模型
    网络通信 --> 同步、异步、阻塞与非阻塞介绍
    网络通信 --> Socket、TCP/IP、HTTP、FTP及网络编程
    SoC总线专题
    RISC-V评估系列
  • 原文地址:https://www.cnblogs.com/kiko2014551511/p/13716718.html
Copyright © 2020-2023  润新知