Java自学者论坛

 找回密码
 立即注册

手机号码,快捷登录

恭喜Java自学者论坛(https://www.javazxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,会员资料板块,购买链接:点击进入购买VIP会员

JAVA高级面试进阶训练营视频教程

Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程Go语言视频零基础入门到精通Java架构师3期(课件+源码)
Java开发全终端实战租房项目视频教程SpringBoot2.X入门到高级使用教程大数据培训第六期全套视频教程深度学习(CNN RNN GAN)算法原理Java亿级流量电商系统视频教程
互联网架构师视频教程年薪50万Spark2.0从入门到精通年薪50万!人工智能学习路线教程年薪50万大数据入门到精通学习路线年薪50万机器学习入门到精通教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程MySQL入门到精通教程
查看: 822|回复: 0

停止redis集群后清除数据重启,Redisson无法自动重连问题解决方法

[复制链接]
  • TA的每日心情
    奋斗
    2024-11-24 15:47
  • 签到天数: 804 天

    [LV.10]以坛为家III

    2053

    主题

    2111

    帖子

    72万

    积分

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    726782
    发表于 2021-8-28 17:00:12 | 显示全部楼层 |阅读模式

    停止redis集群清除数据后重启无法自动重连问题解决方法

     

    问题重现步骤

    1、停止redis集群中的每个节点

    用命令停止逐个节点太麻烦了,写了个shell脚本,shutdown.sh (-a 123456 是redis集群的连接密码)

    redis-cli -p 7001 -a 123456 shutdown
    redis-cli -p 7002 -a 123456 shutdown
    redis-cli -p 7003 -a 123456 shutdown
    redis-cli -p 7004 -a 123456 shutdown
    redis-cli -p 7005 -a 123456 shutdown
    redis-cli -p 7006 -a 123456 shutdown

    执行命令 ./shutdown.sh 停止redis服务

     

    2、清除每个节点产生的数据文件(nodes.conf appendonly.aof  dump.rdb ) 

    执行脚本./moveRedis.sh 清除数据文件

    moveRedis.sh内容为

    cd redis7001
    rm -rf  nodes.conf appendonly.aof  dump.rdb 
    cd ..
    cd redis7002
    rm -rf  nodes.conf appendonly.aof  dump.rdb 
    cd ..
    cd redis7003
    rm -rf  nodes.conf appendonly.aof  dump.rdb 
    cd ..
    cd redis7004
    rm -rf  nodes.conf appendonly.aof  dump.rdb 
    cd ..
    cd redis7005
    rm -rf  nodes.conf appendonly.aof  dump.rdb 
    cd ..
    cd redis7006
    rm -rf  nodes.conf appendonly.aof  dump.rdb 

     

    3、启动redis服务

     执行 ./startall.sh 逐个启动redis服务

     startall.sh脚本内容为

    cd redis7001
    ./redis-server redis.conf
    cd ..
    cd redis7002
    ./redis-server redis.conf
    cd ..
    cd redis7003
    ./redis-server redis.conf
    cd ..
    cd redis7004
    ./redis-server redis.conf
    cd ..
    cd redis7005
    ./redis-server redis.conf
    cd ..
    cd redis7006
    ./redis-server redis.conf

     

    4、创建集群

     进入redis-trib.rb所在目录执行如下命令创建集群

    ./redis-trib.rb  create --replicas  1  192.169.1.71:7001  192.169.1.71:7002  192.169.1.71:7003  192.169.1.71:7004  192.169.1.71:7005  192.169.1.71:7006

     

    程序报错

     以上重现过程程序都是启动着的,redis集群服务起来后redisson并没有自动重连,查看日志发现有如下报错

    org.redisson.client.RedisException: MOVED redirection loop detected. Node //192.169.2.238:9511 has further redirect to //192.169.2.238:9511
        at org.redisson.command.CommandAsyncService.checkAttemptFuture(CommandAsyncService.java:865)
        at org.redisson.command.CommandAsyncService$10.operationComplete(CommandAsyncService.java:673)
        at io.netty.util.concurrent.DefaultPromise.notifyListener0(DefaultPromise.java:511)
        at io.netty.util.concurrent.DefaultPromise.notifyListeners0(DefaultPromise.java:504)
        at io.netty.util.concurrent.DefaultPromise.notifyListenersNow(DefaultPromise.java:483)
        at io.netty.util.concurrent.DefaultPromise.notifyListeners(DefaultPromise.java:424)
        at io.netty.util.concurrent.DefaultPromise.tryFailure(DefaultPromise.java:121)
        at org.redisson.misc.RedissonPromise.tryFailure(RedissonPromise.java:108)
        at org.redisson.client.protocol.CommandData.tryFailure(CommandData.java:78)
        at org.redisson.client.handler.CommandDecoder.decode(CommandDecoder.java:313)
        at org.redisson.client.handler.CommandDecoder.decodeCommand(CommandDecoder.java:128)
        at org.redisson.client.handler.CommandDecoder.decode(CommandDecoder.java:108)
        at io.netty.handler.codec.ByteToMessageDecoder.decodeRemovalReentryProtection(ByteToMessageDecoder.java:489)
        at io.netty.handler.codec.ReplayingDecoder.callDecode(ReplayingDecoder.java:366)
        at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:265)
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362)
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348)
        at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340)
        at io.netty.channel.ChannelInboundHandlerAdapter.channelRead(ChannelInboundHandlerAdapter.java:86)
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362)
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348)
        at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340)
        at io.netty.channel.ChannelInboundHandlerAdapter.channelRead(ChannelInboundHandlerAdapter.java:86)
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362)
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348)
        at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340)
        at io.netty.channel.ChannelInboundHandlerAdapter.channelRead(ChannelInboundHandlerAdapter.java:86)
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362)
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348)
        at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340)
        at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1434)
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362)
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348)
        at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:965)
        at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:163)
        at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:647)
        at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:582)
        at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:499)
        at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:461)
        at io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:884)
        at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
        at java.lang.Thread.run(Thread.java:748)

    解决方案

     最开始怀疑是redisson版本的原因,原来是redisson-3.8.2,将版本提高至3.11.1依旧有这个问题

     然后猜测是不是和redis版本有关,将redis版本由3.2.12升至4.0.14后,问题依然存在

     既然和外部无关,那就只能从程序上优化了

     

    在使用到RedissonClient的方法中捕获异常,一旦出现异常,重新获取一次RedissonClient

     需要注意的是

     手动调用加了@Bean注解的方法无效,需要再写一个用于手动调用的获取RedissonClient的方法

     

     完整代码如下

    package com.xiaonian.middleware.redis;
    
    import com.xiaonian.util.StrUtil;
    import org.redisson.Redisson;
    import org.redisson.api.RedissonClient;
    import org.redisson.config.Config;
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.stereotype.Component;
    
    /**
     * Redisson管理类
     * 连接redis2(缓存redis)
     * @author xiaonian
     * @date 2019/6/26 10:41
     * @version v2.0.0
     */
    @Configuration
    @Component
    public class RedissonManager {
    
        /**redis集群节点*/
        @Value(value = "${spring.redis.cluster.nodes:#{null}}")
        private  String cluster;
        /**redis密码*/
        @Value("${spring.redis.password:#{null}}")
        private String password;
        @Value("${spring.redis.host:#{null}}")
        /**redis单机节点主机*/
        private String host;
        /**redis单机节点端口*/
        @Value("${spring.redis.host:#{null}}")
        private String port;
        /**最大连接数*/
        @Value("${redisson.pool.max.active:30}")
        private int MaxPoolSize;
    
        @Bean
        public RedissonClient getRedisson() {
            return loadRedisson();
        }
    
        public RedissonClient loadRedisson(){
            RedissonClient redisson = null;
            Config config = new Config();
            //单节点
            if(!StrUtil.isEmpty(host)){
                config.useSingleServer().
                        setAddress("redis://"+host+":"+port)
                        .setPassword(password)
                        .setConnectionPoolSize(MaxPoolSize)
                        //最小空闲连接
                        .setConnectionMinimumIdleSize(0);
                redisson = Redisson.create(config);
            }else{
                //集群节点
                String[] nodes = cluster.split(",");
                //redisson版本是3.5,集群的ip前面要加上“redis://”,不然会报错,3.2版本可不加
                for(int i=0;i<nodes.length;i++){
                    nodes = "redis://"+nodes;
                }
                //这是用的集群server
                config.useClusterServers()
                        //设置集群状态扫描时间2000
                        .setScanInterval(2000)
                        .addNodeAddress(nodes)
                        .setPassword(password)
                        .setMasterConnectionPoolSize(MaxPoolSize)
                        //最小空闲连接
                        .setMasterConnectionMinimumIdleSize(0);
                redisson = Redisson.create(config);
    //            System.out.println(config.);
                //可通过打印redisson.getConfig().toJSON().toString()来检测是否配置成功
            }
            return redisson;
        }
    
        public RedissonClient retryGetRedisson() {
           return loadRedisson();
        }
    }

     

    哎...今天够累的,签到来了1...
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|小黑屋|Java自学者论坛 ( 声明:本站文章及资料整理自互联网,用于Java自学者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2024-12-22 13:48 , Processed in 0.059598 second(s), 29 queries .

    Powered by Discuz! X3.4

    Copyright © 2001-2021, Tencent Cloud.

    快速回复 返回顶部 返回列表