解決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;
        }
    }
    
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM