现象:业务代码开发好后,部署到服务器上,刚部署好后应用的访问以及操作都没有问题,当应用运行操作一段时间后将会出现redis连接超时,重新启动应用后,又可以正常运行,运行一段时间后将再次出现redis连接超时。错误信息如下:
分析一:看到连接超时,考虑可能是由于服务器间网络不稳定,设置的超时时间太短导致的,就将超时时间增大到3秒(服务器都是在客户内网,所以网络延迟不会很大),再次将服务器启动,运行一段时间后发现服务器又挂了,错误信息还是上面的。
分析二:超时时间已经增长了,有没有可能是因为用户过多,导致连接占满,后面的用户拿不到连接导致的,然后就将连接池的最大连接数增大到500,再次将服务器启动,运行一段时间后发现服务器又挂了,错误信息还是上面的。
分析三:以上两钟情况都是根据redis的配置考虑的,那有没有可能是因为第一个人使用后的连接一直没有回收使用,然后就通过定时任务解决长期空闲lettuce连接关闭但是netty不能及时监控到的问题,代码如下:
@Scheduled(cron="0/5 * * * * ?")
public void task() {
if(redisConnectionFactory instanceof LettuceConnectionFactory){
LettuceConnectionFactory c=(LettuceConnectionFactory)redisConnectionFactory;
c.validateConnection();
}
同时开启获取连接的校验
@Override
public void afterPropertiesSet() throws Exception {
if(redisConnectionFactory instanceof LettuceConnectionFactory){
LettuceConnectionFactory c=(LettuceConnectionFactory)redisConnectionFactory;
c.setValidateConnection(true);
}
}
再次将服务器启动,这次服务器运行了较长一段时间,直到redis集群其中一台服务器挂了之后再次出现上面的问题。
分析四:前面一段时间都能正常运行,这次是因为redis集群其中一台服务器挂了导致的服务器报错,应该和redis集群有关,然后就查找资料发现:由于当Redis集群中某个节点挂掉之后,lettuce连接池还在使用挂掉的节点信息,Lettuce支持redis 集群拓扑动态刷新,但是默认并没有开启,SpringBoot在集成Lettuce时默认也没有开启,在SpringBoot2.3.0之后才有配置项设置Lettuce自动刷新拓扑的,解决方案参考文档:https://blog.csdn.net/u013202238/article/details/108528650