SpringBoot集成Redis后,运行一段时间后发现RedisCommandTimeoutException

背景:

在项目中引入SpringBoot的autoConfig来管理组件,在集成redis后到沙箱环境运行一段时间后,发现客户端连接redis就会出现超时。

现象:

每次调用redis执行命令的时候会出现下面这个报错:

Caused by: io.lettuce.core.RedisCommandTimeoutException: Command timed out after 1 minute(s)
at io.lettuce.core.ExceptionFactory.createTimeoutException(ExceptionFactory.java:51) ~[lettuce-core-5.1.6.RELEASE.jar!/:?]
at io.lettuce.core.LettuceFutures.awaitOrCancel(LettuceFutures.java:114) ~[lettuce-core-5.1.6.RELEASE.jar!/:?]
at io.lettuce.core.FutureSyncInvocationHandler.handleInvocation(FutureSyncInvocationHandler.java:69) ~[lettuce-core-5.1.6.RELEASE.jar!/:?]
at io.lettuce.core.internal.AbstractInvocationHandler.invoke(AbstractInvocationHandler.java:80) ~[lettuce-core-5.1.6.RELEASE.jar!/:?]
at com.sun.proxy.$Proxy143.get(Unknown Source) ~[?:?]
at org.springframework.data.redis.connection.lettuce.LettuceStringCommands.get(LettuceStringCommands.java:66) ~[spring-data-redis-2.1.8.RELEASE.jar!/:2.1.8.RELEASE]
at org.springframework.data.redis.connection.DefaultedRedisConnection.get(DefaultedRedisConnection.java:253) ~[spring-data-redis-2.1.8.RELEASE.jar!/:2.1.8.RELEASE]
at org.springframework.data.redis.connection.DefaultStringRedisConnection.get(DefaultStringRedisConnection.java:377) ~[spring-data-redis-2.1.8.RELEASE.jar!/:2.1.8.RELEASE]
at org.springframework.data.redis.core.DefaultValueOperations$1.inRedis(DefaultValueOperations.java:57) ~[spring-data-redis-2.1.8.RELEASE.jar!/:2.1.8.RELEASE]
at org.springframework.data.redis.core.AbstractOperations$ValueDeserializingRedisCallback.doInRedis(AbstractOperations.java:59) ~[spring-data-redis-2.1.8.RELEASE.jar!/:2.1.8.RELEASE]
at org.springframework.data.redis.core.RedisTemplate.execute(RedisTemplate.java:224) ~[spring-data-redis-2.1.8.RELEASE.jar!/:2.1.8.RELEASE]
at org.springframework.data.redis.core.RedisTemplate.execute(RedisTemplate.java:184) ~[spring-data-redis-2.1.8.RELEASE.jar!/:2.1.8.RELEASE]
at org.springframework.data.redis.core.AbstractOperations.execute(AbstractOperations.java:95) ~[spring-data-redis-2.1.8.RELEASE.jar!/:2.1.8.RELEASE]
at org.springframework.data.redis.core.DefaultValueOperations.get(DefaultValueOperations.java:53) ~[spring-data-redis-2.1.8.RELEASE.jar!/:2.1.8.RELEASE]
at com.anjuke.api.comboplus.scf.util.RedisUtil.get(RedisUtil.java:28) ~[classes!/:?]
at com.anjuke.api.comboplus.scf.impl.inner.BackWordServiceImpl.flushHouseRedis(BackWordServiceImpl.java:35) ~[classes!/:?]
... 10 more

排查

通过上面的报错,发现是redis超时导致的

于是,执行ping redis域名,发现是正常的。担心是不是端口有问题导致的,telnet 域名 端口,发现端口也是通的。这就很奇怪了。于是开始审视自己的代码,发现了一个不正常的情况:

下面是redis的配置

spring:
  redis:
    host: redis域名
    port: 端口
    password: password
    jedis:
      pool:
        max-active: 16
        max-wait: 5000
        max-idle: 8
        min-idle: 2

发现我配置的是jedis的客户端,但是springBoot加载的redis客户端是lettuce客户端,就怀疑是不是springboot自动注入,加载的redis客户端是不是顺序乱了导致的。

于是,去看了springboot关于redis客户端的自动注入实现:

发现springBoot在自动注入的时候会优先加载lettuce的连接工厂,这就发现配置中的配置没有发挥作用。

SpringBoot集成Redis后,运行一段时间后发现RedisCommandTimeoutException_第1张图片

排查到此,也有了怀疑,为啥lettuce默认的配置会导致redis出现超时呢?于是在同事的建议下到lettuce的GitHub工程里面,看了下,lettuce是有这个bug的。看了下,发现可能是由于io底层与云平台不兼容导致,然后redis底层容器中的连接没有了,调用的时候再去拿去连接,无法生成连接,然后,由于maxWait默认值是-1(永久等待)。所以执行的时候导致超时。

具体的ISSUE地址:https://github.com/lettuce-io/lettuce-core/issues

当然以上只是推测,没有去验证,后面有空了,去验证下是不是上述的原因。

解决

把springBoot中lettuce-core的jarexclude掉。让SpringBoot使用jedis去加载它。

 

你可能感兴趣的:(工作学习总结,java)