怪异的redis异常
实现一个监控服务,监控其他服务的运行状态并校验相应的业务数据,设计上使用redis来传递心跳和业务数据来解耦,避免影响到主流程。然而不同的监控对象使用的redis库不尽相同,业务上需要实现动态redis库的功能,首先尝试在网络上寻找到工具类如下
1 |
|
可以看到setDataBase方法是通过注入设置了db号的connectionFactory对象来实现的切换redisTemplete。这一方式在单线程场景中没有什么问题,但是一旦进行异步调用,则偶发抛出io.lettuce.core.RedisException:异常提示Connection is closed
在测试中还发现,当使用仅仅使用单一的redis库时并不会抛出这一异常,当使用不同的redis库时,偶发的抛出这一异常,且接口调用越频繁异常越容易抛出。甚至可能导致服务崩溃
问题原因
在RedisConfig中获取到的redisTemplete为单例,在这种动态db库的方式下,当异步调用过程中存在着在某一线程中正在使用DB1的时,其他线程尝试以DB2的连接访问redis的情况,而redisTemplate实例中的连接已经不是DB2了,从而抛出该异常。
解决方案
更换RedisConfig类,在项目启动时一次性新建预先配置了DB的redis连接池,根据不同DB号获得不同实例的redisTemplate。
1 |
|