转载

处理redis集群宕机恢复后程序不恢复问题

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;
        }
    }
    
}
正文到此结束
Loading...