停⽌redis集后清除数据重启,Redisson⽆法⾃动重连问题解决⽅法
停⽌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、清除每个节点产⽣的数据⽂件(f appendonly.aof dump.rdb )
执⾏脚本./moveRedis.sh 清除数据⽂件
moveRedis.sh内容为
cd redis7001
rm -rf f appendonly.aof dump.rdb
cd ..
cd redis7002
rm -rf f appendonly.aof dump.rdb
cd ..
cd redis7003
rm -rf f appendonly.aof dump.rdb
cd ..
cd redis7004
rm -rf f appendonly.aof dump.rdb
cd ..
cd redis7005
rm -rf f appendonly.aof dump.rdb
cd ..
cd redis7006
rm -rf f appendonly.aof dump.rdb
3、启动redis服务
执⾏ ./startall.sh 逐个启动redis服务
startall.sh脚本内容为
cd redis7001
./f
cd ..
cd redis7002
./f
cd ..
cd redis7003
./f
cd ..
cd redis7004
./f
cd ..
cd redis7005
./f
cd ..
cd redis7006
./f
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并没有⾃动重连,查看⽇志发现有如下报错
dissonmand.CommandAsyncService.checkAttemptFuture(CommandAsyncService.java:865)
dissonmand.CommandAsyncService$10.operationComplete(CommandAsyncService.java:673)
at ifyListener0(DefaultPromise.java:511)
at ifyListeners0(DefaultPromise.java:504)
at ifyListenersNow(DefaultPromise.java:483)
at ifyListeners(DefaultPromise.java:424)
at Failure(DefaultPromise.java:121)
disson.Failure(RedissonPromise.java:108)
disson.client.Failure(CommandData.java:78)
disson.client.handler.CommandDecoder.decode(CommandDecoder.java:313)
disson.client.handler.CommandDecoder.decodeCommand(CommandDecoder.java:128)
disson.client.handler.CommandDecoder.decode(CommandDecoder.java:108)
at dec.ByteToMessageDecoder.decodeRemovalReentryProtection(ByteToMessageDecoder.java:489) at dec.ReplayingDecoder.callDecode(ReplayingDecoder.java:366)
at dec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:265)
at ioty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362)
at ioty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348)
at ioty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340)
at ioty.channel.ChannelInboundHandlerAdapter.channelRead(ChannelInboundHandlerAdapter.java:86)
at ioty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362)
at ioty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348)
at ioty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340)
at ioty.channel.ChannelInboundHandlerAdapter.channelRead(ChannelInboundHandlerAdapter.java:86)
at ioty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362)
at ioty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348)
at ioty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340)
at ioty.channel.ChannelInboundHandlerAdapter.channelRead(ChannelInboundHandlerAdapter.java:86)
at ioty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362)
at ioty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348)
at ioty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340)
at ioty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1434)
at ioty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362)
at ioty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348)
at ioty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:965)
at ioty.channel.nio.ad(AbstractNioByteChannel.java:163)
at ioty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:647)
at ioty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:582)
at ioty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:499)
at ioty.channel.nio.NioEventLoop.run(NioEventLoop.java:461)
at urrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:884)
at urrent.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.dis;
import com.xiaonian.util.StrUtil;
disson.Redisson;
disson.api.RedissonClient;spring framework版本查看
fig.Config;
import org.springframework.beans.factory.annotation.Value;
import t.annotation.Bean;
import t.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 = "${des:#{null}}")
private String cluster;
/
**redis密码*/
@Value("${dis.password:#{null}}")
private String password;
@Value("${dis.host:#{null}}")
/**redis单机节点主机*/
private String host;
/**redis单机节点端⼝*/
@Value("${dis.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 = ate(config);
}else{
//集节点
String[] nodes = cluster.split(",");
//redisson版本是3.5,集的ip前⾯要加上“redis://”,不然会报错,3.2版本可不加for(int i=0;i<nodes.length;i++){
nodes[i] = "redis://"+nodes[i];
}
//这是⽤的集server
config.useClusterServers()
//设置集状态扫描时间2000
.setScanInterval(2000)
.addNodeAddress(nodes)
.setPassword(password)
.setMasterConnectionPoolSize(MaxPoolSize)
//最⼩空闲连接
.setMasterConnectionMinimumIdleSize(0);
redisson = ate(config);
/
/ System.out.println(config.);
//可通过打印Config().toJSON().toString()来检测是否配置成功
}
return redisson;
}
public RedissonClient retryGetRedisson() {
return loadRedisson();
}
}
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论