【Redis连接超时】nested exception is java.lang.reflect.UndeclaredThrowableException

【Redis连接超时】nested exception is java.lang.reflect.UndeclaredThrowableException,第1张

问题

公司的一个Springboot项目最近上线到生产环境,但是上去之后一直报redis连接超时的问题

2022-05-05 13:15:50 org.springframework.data.redis.RedisSystemException: Unknown redis exception; nested exception is java.lang.reflect.UndeclaredThrowableException
2022-05-05 13:15:50 	at org.springframework.data.redis.FallbackExceptionTranslationStrategy.getFallback(FallbackExceptionTranslationStrategy.java:53) ~[spring-data-redis-2.1.18.RELEASE.jar!/:2.1.18.RELEASE]
2022-05-05 13:15:50 	at org.springframework.data.redis.FallbackExceptionTranslationStrategy.translate(FallbackExceptionTranslationStrategy.java:43) ~[spring-data-redis-2.1.18.RELEASE.jar!/:2.1.18.RELEASE]
2022-05-05 13:15:50 	at org.springframework.data.redis.connection.lettuce.LettuceConnection.convertLettuceAccessException(LettuceConnection.java:268) ~[spring-data-redis-2.1.18.RELEASE.jar!/:2.1.18.RELEASE]
2022-05-05 13:15:50 	at org.springframework.data.redis.connection.lettuce.LettuceHashCommands.convertLettuceAccessException(LettuceHashCommands.java:471) ~[spring-data-redis-2.1.18.RELEASE.jar!/:2.1.18.RELEASE]
2022-05-05 13:15:50 	at org.springframework.data.redis.connection.lettuce.LettuceHashCommands.hGet(LettuceHashCommands.java:172) ~[spring-data-redis-2.1.18.RELEASE.jar!/:2.1.18.RELEASE]
2022-05-05 13:15:50 	at org.springframework.data.redis.connection.DefaultedRedisConnection.hGet(DefaultedRedisConnection.java:926) ~[spring-data-redis-2.1.18.RELEASE.jar!/:2.1.18.RELEASE]
2022-05-05 13:15:50 	at org.springframework.data.redis.core.DefaultHashOperations.lambda$get<(DefaultHashOperations.java:53) ~[spring-data-redis-2.1.18.RELEASE.jar!/:2.1.18.RELEASE]
2022-05-05 13:15:50 	at org.springframework.data.redis.core.RedisTemplate.execute(RedisTemplate.java:225) ~[spring-data-redis-2.1.18.RELEASE.jar!/:2.1.18.RELEASE]
2022-05-05 13:15:50 	at org.springframework.data.redis.core.RedisTemplate.execute(RedisTemplate.java:185) ~[spring-data-redis-2.1.18.RELEASE.jar!/:2.1.18.RELEASE]
2022-05-05 13:15:50 	at org.springframework.data.redis.core.AbstractOperations.execute(AbstractOperations.java:96) ~[spring-data-redis-2.1.18.RELEASE.jar!/:2.1.18.RELEASE]
2022-05-05 13:15:50 	at org.springframework.data.redis.core.DefaultHashOperations.get(DefaultHashOperations.java:53) ~[spring-data-redis-2.1.18.RELEASE.jar!/:2.1.18.RELEASE]

...

2022-05-05 13:15:50 Caused by: java.lang.reflect.UndeclaredThrowableException: null
2022-05-05 13:15:50 	at com.sun.proxy.$Proxy162.hget(Unknown Source) ~[na:na]
2022-05-05 13:15:50 	at org.springframework.data.redis.connection.lettuce.LettuceHashCommands.hGet(LettuceHashCommands.java:170) ~[spring-data-redis-2.1.18.RELEASE.jar!/:2.1.18.RELEASE]
2022-05-05 13:15:50 	... 92 common frames omitted
2022-05-05 13:15:50 Caused by: java.lang.reflect.InvocationTargetException: null
2022-05-05 13:15:50 	at sun.reflect.GeneratedMethodAccessor208.invoke(Unknown Source) ~[na:na]
2022-05-05 13:15:50 	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_331]
2022-05-05 13:15:50 	at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_331]
2022-05-05 13:15:50 	at com.tencent.tsf.sleuth.instrument.redis.TracingRedisHandler.invoke(TracingRedisHandler.java:55) ~[spring-cloud-tsf-sleuth-1.24.0-Greenwich-RELEASE.jar!/:1.24.0-Greenwich-RELEASE]
2022-05-05 13:15:50 	... 94 common frames omitted
2022-05-05 13:15:50 Caused by: io.lettuce.core.RedisCommandTimeoutException: Command timed out after 1 second(s)
2022-05-05 13:15:50 	at io.lettuce.core.ExceptionFactory.createTimeoutException(ExceptionFactory.java:51) ~[lettuce-core-5.1.8.RELEASE.jar!/:na]
2022-05-05 13:15:50 	at io.lettuce.core.LettuceFutures.awaitOrCancel(LettuceFutures.java:114) ~[lettuce-core-5.1.8.RELEASE.jar!/:na]
2022-05-05 13:15:50 	at io.lettuce.core.FutureSyncInvocationHandler.handleInvocation(FutureSyncInvocationHandler.java:69) ~[lettuce-core-5.1.8.RELEASE.jar!/:na]
2022-05-05 13:15:50 	at io.lettuce.core.internal.AbstractInvocationHandler.invoke(AbstractInvocationHandler.java:80) ~[lettuce-core-5.1.8.RELEASE.jar!/:na]
2022-05-05 13:15:50 	at com.sun.proxy.$Proxy159.hget(Unknown Source) ~[na:na]
2022-05-05 13:15:50 	... 98 common frames omitted

redis服务端的最大连接数已经设置到足够大,在项目刚启动时是能正常获取到redis连接的,但是当程序闲置几分钟后,后台日志就开始刷redis连接超时的问题

根源

没有配置redis连接池,导致每次需要访问redis时都需要去重新获取redis连接。

解决方案

使用jedis连接池

配置jedis连接池 引入依赖
		<dependency>
            groupId>redis.clients<groupId>
            artifactId>jedisartifactId>
        springdependency>
yaml文件增加连接池配置
:redis
  :host
    :port 127.0.0.1
    :6379 password
    :timeout edith
    :5000 jedis
    :pool
      :max-active
        :20 max-wait
        :3000 max-idle
        :10 min-idle
        :8 import
Redis配置类
. com.fasterxml.jackson.annotationJsonAutoDetect;import
. com.fasterxml.jackson.annotationPropertyAccessor;import
. com.fasterxml.jackson.databindObjectMapper;import
. lombok.extern.slf4jSlf4j;import
. org.springframework.beans.factory.annotationValue;import
. org.springframework.context.annotationBean;import
. org.springframework.context.annotationConfiguration;import
. org.springframework.data.redis.connectionRedisPassword;import
. org.springframework.data.redis.connectionRedisStandaloneConfiguration;import
. org.springframework.data.redis.connection.jedisJedisConnectionFactory;import
. org.springframework.data.redis.coreRedisTemplate;import
. org.springframework.data.redis.serializerJackson2JsonRedisSerializer;import
. org.springframework.data.redis.serializerStringRedisSerializer;import
. redis.clients.jedisJedisPoolConfig;//import com.fasterxml.jackson.databind.jsontype.impl.LaissezFaireSubTypeValidator;

@Slf4j

@Configuration
public
class RedisConfig @Value {

        ("${spring.redis.host}")private
        String ; host@Value
        ("${spring.redis.port}")private
        Integer ; port@Value
        ("${spring.redis.password}")private
        String ; password@Value

        ("${spring.redis.jedis.pool.max-active}")private
        Integer ; maxActive@Value
        ("${spring.redis.jedis.pool.max-idle}")private
        Integer ; maxIdle@Value
        ("${spring.redis.jedis.pool.max-wait}")private
        Long ; maxWait@Value
        ("${spring.redis.jedis.pool.min-idle}")private
        Integer ; minIdle@Bean

    (=name "jedisConnectionFactory" )public
    JedisConnectionFactory jedisConnectionFactory ()RedisStandaloneConfiguration {
        = jedisConfig new RedisStandaloneConfiguration ();.
        jedisConfigsetHostName()host;.
        jedisConfigsetPort()port;.
        jedisConfigsetPassword(RedisPassword.of()password);JedisPoolConfig
        = jedisPoolConfig new JedisPoolConfig ();.
        jedisPoolConfigsetMaxIdle()maxIdle;.
        jedisPoolConfigsetMaxWaitMillis()maxWait;.
        jedisPoolConfigsetMaxTotal()maxActive;.
        jedisPoolConfigsetMinIdle()minIdle;JedisConnectionFactory
        = jedisConnectionFactory new JedisConnectionFactory ()jedisConfig;.
        jedisConnectionFactorysetPoolConfig()jedisPoolConfig;.
        loginfo()"【redis连接池初始化】>>>>>>>>>>> JedisPool注入成功!!";.
        loginfo(,"【redis连接池初始化】>>>>>>>>>>> redis地址:{}:{}" , host ) port;return
        ; jedisConnectionFactory}
    @Bean

    public
    RedisTemplate <String,ObjectredisTemplate> (JedisConnectionFactory) jedisConnectionFactoryRedisTemplate{
        <String,Object => template new RedisTemplate <(>);.
        templatesetConnectionFactory()jedisConnectionFactory;Jackson2JsonRedisSerializer

        = jackson2JsonRedisSerializer new Jackson2JsonRedisSerializer (Object.class);ObjectMapper
        = om new ObjectMapper ();.
        omsetVisibility(PropertyAccessor.,ALL. JsonAutoDetect.Visibility)ANY;.
        omenableDefaultTyping(.ObjectMapper.DefaultTyping)NON_FINAL;.
        jackson2JsonRedisSerializersetObjectMapper()om;StringRedisSerializer

        = stringRedisSerializer new StringRedisSerializer ();// key采用String的序列化方式
        .
        templatesetKeySerializer()stringRedisSerializer;// hash的key也采用String的序列化方式
        .
        templatesetHashKeySerializer()stringRedisSerializer;// value序列化方式采用jackson
        .
        templatesetValueSerializer()stringRedisSerializer;// hash的value序列化方式采用jackson
        .
        templatesetHashValueSerializer()stringRedisSerializer;.
        templateafterPropertiesSet();return

        ; template}
    }

写在最后

网上有种说法是

springboot 2.x 默认采用了lettuce作为连接池,但是lettuce是不会进行“心跳” *** 作的,也就是说,它不会保持连接,导致了连接超时。

笔者使没验证长期空闲lettuce连接超时的问题,有哪位大佬可以讨论一下这个东西?

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/langs/799492.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2022-05-06
下一篇2022-05-06

发表评论

登录后才能评论

评论列表(0条)

    保存