Spring Boot Redis 断连重试解析

Spring Boot Redis 断连重试解析

Spring Boot Redis 断连重试解析

由于我想试试Spring Boot Redis中是否有断连重试机制以及尝试修改域名的Ip地址Redis是否会重新解析,为了验证和搞清楚,为此我进行了一次模拟。

首先,我在我的Windows电脑中hosts文件中添加了一个域名redis.mytest.xin,里面指向的IP为192.168.40.11,同时项目中Redis的Host配置也是域名。

停止Redis

将Redis停止后,控制台中里面输出了日志:

2019-07-11 10:50:08.379 DEBUG io.lettuce.core.protocol.CommandHandler 290 channelInactive - [channel=0x8994356b, /192.168.40.11:57118 -> redis.mytest.xin/192.168.40.11:6379, chid=0x1] channelInactive()
2019-07-11 10:50:08.380 DEBUG io.lettuce.core.protocol.DefaultEndpoint 404 lambda$notifyChannelInactive$1 - [channel=0x8994356b, /192.168.40.11:57118 -> redis.mytest.xin/192.168.40.11:6379, epid=0x1] deactivating endpoint handler
2019-07-11 10:50:08.380 DEBUG io.lettuce.core.protocol.DefaultEndpoint 554 lambda$notifyDrainQueuedCommands$4 - [channel=0x8994356b, /192.168.40.11:57118 -> redis.mytest.xin/192.168.40.11:6379, epid=0x1] notifyQueuedCommands adding 0 command(s) to buffer
2019-07-11 10:50:08.380 DEBUG io.lettuce.core.protocol.CommandHandler 315 channelInactive - [channel=0x8994356b, /192.168.40.11:57118 -> redis.mytest.xin/192.168.40.11:6379, chid=0x1] channelInactive() done
2019-07-11 10:50:08.380 DEBUG io.lettuce.core.protocol.ConnectionWatchdog 167 channelInactive - [channel=0x8994356b, /192.168.40.11:57118 -> redis.mytest.xin/192.168.40.11:6379, last known addr=redis.mytest.xin/192.168.40.11:6379] channelInactive()
2019-07-11 10:50:08.381 DEBUG io.lettuce.core.protocol.ConnectionWatchdog 197 scheduleReconnect - [channel=0x8994356b, /192.168.40.11:57118 -> redis.mytest.xin/192.168.40.11:6379, last known addr=redis.mytest.xin/192.168.40.11:6379] scheduleReconnect()
2019-07-11 10:50:08.381 DEBUG io.lettuce.core.protocol.ConnectionWatchdog 214 scheduleReconnect - [channel=0x8994356b, /192.168.40.11:57118 -> redis.mytest.xin/192.168.40.11:6379, last known addr=redis.mytest.xin/192.168.40.11:6379] Reconnect attempt 1, delay 1ms
2019-07-11 10:50:08.384 DEBUG io.lettuce.core.protocol.ConnectionWatchdog 167 channelInactive - [channel=0x8994356b, /192.168.40.11:57118 -> redis.mytest.xin/192.168.40.11:6379, last known addr=redis.mytest.xin/192.168.40.11:6379] channelInactive()
2019-07-11 10:50:08.384 DEBUG io.lettuce.core.protocol.ConnectionWatchdog 197 scheduleReconnect - [channel=0x8994356b, /192.168.40.11:57118 -> redis.mytest.xin/192.168.40.11:6379, last known addr=redis.mytest.xin/192.168.40.11:6379] scheduleReconnect()
2019-07-11 10:50:08.384 DEBUG io.lettuce.core.protocol.ConnectionWatchdog 236 scheduleReconnect - [channel=0x8994356b, /192.168.40.11:57118 -> redis.mytest.xin/192.168.40.11:6379, last known addr=redis.mytest.xin/192.168.40.11:6379] Skipping scheduleReconnect() because I have an active channel
2019-07-11 10:50:08.384 DEBUG io.lettuce.core.protocol.CommandHandler 161 channelUnregistered - [channel=0x8994356b, /192.168.40.11:57118 -> redis.mytest.xin/192.168.40.11:6379, chid=0x1] channelUnregistered()
2019-07-11 10:50:08.486 INFO  io.netty.util.internal.logging.AbstractInternalLogger 173 log - Reconnecting, last destination was redis.mytest.xin/192.168.40.11:6379

这些日志中,io.lettuce.core.protocol.CommandHandler#channelInactive它做了以下操作:

Spring Boot Redis 断连重试解析-1

  • 设置当前的生命周期状态为断开
  • 设置当前的生命周期状态为不可用
  • 通知并将当前的channel的连接设置为不可用并将的channel设置为空
  • 通知并停止队中等待执行的命令,并将命令添加在缓存中
  • 设置当前的生命周期状态为不可用
  • 如果开启了保护模式,则执行相关的模式的策略
  • 重置Redis状态
  • 尝试重新连接Redis

执行到了尝试重新连接Redis时,会调用到io.lettuce.core.protocol.ConnectionWatchdog#channelInactive这个方法,它做了以下操作:

Spring Boot Redis 断连重试解析-2

  • 计划重新连接
  • 执行相关的触发器

先看看第一步,计划重新连接,它做了以下操作:

Spring Boot Redis 断连重试解析-3

  • 添加重连定时器
  • 提交需要执行重新连接的任务

继续下一步,查看io.lettuce.core.protocol.ConnectionWatchdog#run中的重新连接方法:

Spring Boot Redis 断连重试解析-4

  • 添加重新连接的监听器
  • 重新连接并且解析域名的IP
  • 添加连接后的监听器
  • 检查是否还需要继续尝试重新连接

执行完以上的步骤后,将会去执行相关的连接事件触发器io.lettuce.core.ConnectionEventTrigger#channelInactive,并且再次执行刚刚的重新连接步骤,直到成功为止。

修改hosts中域名指向的IP地址

重连已经得以验证是没问题的,那么试试修改域名指向的IP地址后,停止之前连接Redis,不重启现有的项目,是否会重新解析域名的IP。

首先做好准备工作:

  • 准备两台Redis(这里准备了两台Redis,IP分别为192.168.40.11192.168.40.239
  • 在Hosts文件中添加域名指向的IP(这里我使用的是redis.mytest.xin域名,hosts文件内容192.168.40.11 redis.mytest.xin
  • 修改Redis连接配置中的Host,将其改为域名

启动程序

我们先看看两台Redis中Key,确保两边的Key是不一样的,用于判断是不同的机器:

Spring Boot Redis 断连重试解析-5

Spring Boot Redis 断连重试解析-6

验证无误后,启动应用程序,并且查看控制台输出的日志:

Spring Boot Redis 断连重试解析-7

控制台输出的Keys为空,并且解析到的域名IP也是192.168.40.11。现在我将Hosts文件中的IP改为192.168.40.239

Spring Boot Redis 断连重试解析-8

改完后,我停止192.168.40.11这台服务器中的Redis,并且查看控制控制台输出的日志:

Spring Boot Redis 断连重试解析-9

可以看到,在停止了192.168.40.11这台服务器中的Redis后,立马就触发了重新连接的事件,并且尝试重新连接,对域名进行了解析的同时也获取到了新的IP。在这个过程,并没有重新启动项目。

总结

经过尝试,可以得出结论:

  • 当Redis宕机后,会有相关的触发器或者事件,调用重新连接的方法尝试重新连接,直到连接成功为止。
  • 修改了Hosts后,需要将原来的Redis关闭才会触发重新连接的事件,并且对域名重新进行解析。

评论

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×