Java连接redis报错timed out问题的解决办法

 更新时间:2024年02月13日 10:00:56   作者:坚持是一种态度  
最近项目开发中用到了Redis,下面这篇文章主要给大家介绍了关于Java连接redis报错timed out问题的解决办法,文中通过代码介绍的非常详细,需要的朋友可以参考下

现象

  • 之前写了一篇文章:Spring redis使用报错Read timed out排查解决,解决超时问题
  • 后面发现解决的不彻底,仍有报错
  • 详细查看了下源码,发现不同版本里,参数名不一样,之前的参数设置,并没有在新版本里生效

报错一

  • 核心报错提示是这一句:JedisConnectionException: java.net.SocketTimeoutException: Read timed out
  • 使用jedis连接时,连接超时SocketTimeout,即与Redis服务器的连接超时
2023-03-29 10:54:38.186 ERROR 9136 --- [ntainer#7-0-C-1] c.n.r.service.IntersectionQueryService   : Exception in getIntersectionById() with cause = 'redis.clients.jedis.exceptions.JedisConnectionException: java.net.SocketTimeoutException: Read timed out' and exception = 'java.net.SocketTimeoutException: Read timed out; nested exception is redis.clients.jedis.exceptions.JedisConnectionException: java.net.SocketTimeoutException: Read timed out'

org.springframework.data.redis.RedisConnectionFailureException: java.net.SocketTimeoutException: Read timed out; nested exception is redis.clients.jedis.exceptions.JedisConnectionException: java.net.SocketTimeoutException: Read timed out
	at org.springframework.data.redis.connection.jedis.JedisExceptionConverter.convert(JedisExceptionConverter.java:65)
	at org.springframework.data.redis.connection.jedis.JedisExceptionConverter.convert(JedisExceptionConverter.java:42)
	at org.springframework.data.redis.PassThroughExceptionTranslationStrategy.translate(PassThroughExceptionTranslationStrategy.java:44)
	at org.springframework.data.redis.FallbackExceptionTranslationStrategy.translate(FallbackExceptionTranslationStrategy.java:42)
	at org.springframework.data.redis.connection.jedis.JedisConnection.convertJedisAccessException(JedisConnection.java:187)
	at org.springframework.data.redis.connection.jedis.JedisConnection.doWithJedis(JedisConnection.java:802)
	at org.springframework.data.redis.connection.jedis.JedisConnection.doInvoke(JedisConnection.java:160)
	at org.springframework.data.redis.connection.jedis.JedisConnection.lambda$new$0(JedisConnection.java:69)
	at org.springframework.data.redis.connection.jedis.JedisInvoker$Synchronizer.invoke(JedisInvoker.java:1027)
	at org.springframework.data.redis.connection.jedis.JedisInvoker$DefaultSingleInvocationSpec.getOrElse(JedisInvoker.java:946)
	at org.springframework.data.redis.connection.jedis.JedisStringCommands.setEx(JedisStringCommands.java:176)
	at org.springframework.data.redis.connection.DefaultedRedisConnection.setEx(DefaultedRedisConnection.java:334)
	at org.springframework.data.redis.connection.DefaultStringRedisConnection.setEx(DefaultStringRedisConnection.java:1138)
	at org.springframework.data.redis.core.DefaultValueOperations$8.potentiallyUsePsetEx(DefaultValueOperations.java:337)
	at org.springframework.data.redis.core.DefaultValueOperations$8.doInRedis(DefaultValueOperations.java:330)
	at org.springframework.data.redis.core.RedisTemplate.execute(RedisTemplate.java:223)
	at org.springframework.data.redis.core.RedisTemplate.execute(RedisTemplate.java:190)
	at org.springframework.data.redis.core.AbstractOperations.execute(AbstractOperations.java:97)
	at org.springframework.data.redis.core.DefaultValueOperations.set(DefaultValueOperations.java:325)
	at com.newatc.radar.service.IntersectionQueryService.getAllIntersections(IntersectionQueryService.java:70)

报错二

  • 核心报错提示是这一句: Error while validating pooled Jedis object
  • 连接池内的Jedis对象已经失效或已经关闭,没有可用的jedis客户端
2023-08-24 09:44:23.721 ERROR 92250 --- [ns-pool-evictor] redis.clients.jedis.JedisFactory         : Error while validating pooled Jedis object.

redis.clients.jedis.exceptions.JedisConnectionException: java.net.SocketTimeoutException: Read timed out
	at redis.clients.jedis.util.RedisInputStream.ensureFill(RedisInputStream.java:205)
	at redis.clients.jedis.util.RedisInputStream.readByte(RedisInputStream.java:43)
	at redis.clients.jedis.Protocol.process(Protocol.java:162)
	at redis.clients.jedis.Protocol.read(Protocol.java:227)
	at redis.clients.jedis.Connection.readProtocolWithCheckingBroken(Connection.java:352)
	at redis.clients.jedis.Connection.getStatusCodeReply(Connection.java:270)
	at redis.clients.jedis.BinaryJedis.ping(BinaryJedis.java:380)
	at redis.clients.jedis.JedisFactory.validateObject(JedisFactory.java:214)
	at org.apache.commons.pool2.impl.GenericObjectPool.evict(GenericObjectPool.java:745)
	at org.apache.commons.pool2.impl.BaseGenericObjectPool$Evictor.run(BaseGenericObjectPool.java:160)
	at org.apache.commons.pool2.impl.EvictionTimer$WeakRunner.run(EvictionTimer.java:113)
	at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515)
	at java.base/java.util.concurrent.FutureTask.runAndReset(FutureTask.java:305)
	at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:305)
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
	at java.base/java.lang.Thread.run(Thread.java:829)
Caused by: java.net.SocketTimeoutException: Read timed out
	at java.base/java.net.SocketInputStream.socketRead0(Native Method)
	at java.base/java.net.SocketInputStream.socketRead(SocketInputStream.java:115)
	at java.base/java.net.SocketInputStream.read(SocketInputStream.java:168)
	at java.base/java.net.SocketInputStream.read(SocketInputStream.java:140)
	at java.base/java.net.SocketInputStream.read(SocketInputStream.java:126)
	at redis.clients.jedis.util.RedisInputStream.ensureFill(RedisInputStream.java:199)
	... 16 common frames omitted

2023-08-24 09:44:25.724 ERROR 92250 --- [ns-pool-evictor] redis.clients.jedis.JedisFactory         : Error while validating pooled Jedis object.

redis.clients.jedis.exceptions.JedisConnectionException: java.net.SocketTimeoutException: Read timed out
	at redis.clients.jedis.util.RedisInputStream.ensureFill(RedisInputStream.java:205)
	at redis.clients.jedis.util.RedisInputStream.readByte(RedisInputStream.java:43)
	at redis.clients.jedis.Protocol.process(Protocol.java:162)
	at redis.clients.jedis.Protocol.read(Protocol.java:227)
	at redis.clients.jedis.Connection.readProtocolWithCheckingBroken(Connection.java:352)
	at redis.clients.jedis.Connection.getStatusCodeReply(Connection.java:270)
	at redis.clients.jedis.BinaryJedis.ping(BinaryJedis.java:380)
	at redis.clients.jedis.JedisFactory.validateObject(JedisFactory.java:214)
	at org.apache.commons.pool2.impl.GenericObjectPool.evict(GenericObjectPool.java:745)
	at org.apache.commons.pool2.impl.BaseGenericObjectPool$Evictor.run(BaseGenericObjectPool.java:160)
	at org.apache.commons.pool2.impl.EvictionTimer$WeakRunner.run(EvictionTimer.java:113)
	at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515)
	at java.base/java.util.concurrent.FutureTask.runAndReset(FutureTask.java:305)
	at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:305)
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
	at java.base/java.lang.Thread.run(Thread.java:829)
Caused by: java.net.SocketTimeoutException: Read timed out
	at java.base/java.net.SocketInputStream.socketRead0(Native Method)
	at java.base/java.net.SocketInputStream.socketRead(SocketInputStream.java:115)
	at java.base/java.net.SocketInputStream.read(SocketInputStream.java:168)
	at java.base/java.net.SocketInputStream.read(SocketInputStream.java:140)
	at java.base/java.net.SocketInputStream.read(SocketInputStream.java:126)
	at redis.clients.jedis.util.RedisInputStream.ensureFill(RedisInputStream.java:199)
	... 16 common frames omitted

解决

  • 报错是发生在我们的环境,事实上,我们的平台并没有那么高的并发量,只有一些造数据脚本在跑和调用redis
  • 而且所有应用服务和redis服务,都在一个内网环境里,不应该有网络波动的问题,但发生这个报错时,使用可视化工具连接redis,可以发现,Redis服务是正常的
  • 最终发现,是我们没有针对新版本,配置好超时参数
  • 原有配置
spring:
  redis:
    host: 192.168.1.50
    port: 6379
    password:
    database: 0
    jedis:
      pool:
        min-idle: 10
        max-idle: 400
        max-wait: 30000
        max-active: 200
  • 查看了源码后发现,少了对于redis客户端连接维护的超时时间设置,这个超时时间默认是2s,有时候是不够用的
  • 当大并发量来临,或者大量对象存储更新时,阻塞可能会超过2s时,就会报错SocketTimeoutException
  • 新的配置(时间可以写毫秒,也可以带单位)
  • spring.redis.timeout:是指与redis服务器的读写超时时间,读写操作时会判断这个
  • spring.redis.connect-timeout:是指与redis服务器的连接超时时间,默认2s,这个可以设置大一点,例如30s,保证短时的网络波动不影响连接
  • spring.redis.jedis.pool.min-idle:最小空闲连接,可以根据需要写,我这里设置为8
  • spring.redis.jedis.pool.max-idle:最大空闲连接,可以根据需要写,我这里设置为200,够用了
  • spring.redis.jedis.pool.max-wait:连接池最大阻塞等待时间(使用负值表示没有限制),这个是指服务从连接池获取连接的等待时间,我这里设置为30s,够用了
  • spring.redis.jedis.pool.max-active:连接池最大连接数(使用负值表示没有限制),根据我们的应用数量设置,我这里设置256,足够用了
spring:
  redis:
    host: 192.168.1.50
    port: 6379
    password:
    database: 0
    timeout: 30s # 读写超时
    connect-timeout: 60s #连接超时
    jedis:
      pool:
        min-idle: 8 # 最小空闲连接
        max-idle: 200 # 最大空闲连接
        max-wait: 30s # 连接池最大阻塞等待时间(使用负值表示没有限制)
        max-active: 256 # 连接池最大连接数(使用负值表示没有限制)
  • 总结一下,一开始只配置了参数spring.redis.jedis.pool.max-wait连接池最大阻塞等待时间,而没有配置spring.redis.timeoutspring.redis.connect-timeout,导致偶发的超时
  • 配置上这两个参数后,就没有遇到超时报错了
  • 最后再介绍下Jedis连接池吧

Jedis连接池

Jedis连接池是用于管理Jedis客户端连接的一种机制。Jedis是一个非常流行的Java Redis客户端,它允许Java开发人员与Redis服务器进行交互。

Jedis连接池的目的是为了提高应用程序与Redis服务器之间的性能和可扩展性。通过连接池,应用程序可以重复利用现有的连接而不是创建新的连接,从而减少连接的创建和销毁的开销。

Jedis连接池的实现中有几个主要的组件:

  • 连接池配置(Config):用于设置连接池的参数,如最大连接数、最大空闲连接数、连接超时时间等。

  • 连接池对象(JedisPool):用于创建和管理Jedis连接。

  • Jedis连接(Jedis):用于与Redis服务器进行交互的对象。

连接池的工作原理如下:

  • 初始化:当连接池被创建时,它会根据配置参数建立一定数量的连接,并放入连接池中。
  • 借用连接:当应用程序需要与Redis服务器进行交互时,它可以从连接池中获取一个空闲连接。
  • 使用连接:应用程序使用连接进行操作,如执行命令、读写数据等操作。
  • 归还连接:应用程序完成操作后,将连接归还给连接池,以便其他线程或请求可以继续使用该连接。
  • 连接池管理:连接池会根据预设的策略来管理连接的状态,如连接的获取、释放、逐出等。

使用Jedis连接池可以提高应用程序与Redis服务器之间的性能和资源利用率。通过合理配置连接池的参数,可以控制连接数、连接超时时间、最大空闲连接数等,以适应不同规模的应用程序需求。同时,连接池还可以提供连接的可用性检查、自动重连、连接汇报等功能,提高应用的可靠性和稳定性。

总结

到此这篇关于Java连接redis报错timed out问题解决的文章就介绍到这了,更多相关Java连接redis报错timed out内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • java:try...catch跳过异常继续处理循环问题

    java:try...catch跳过异常继续处理循环问题

    这篇文章主要介绍了java:try...catch跳过异常继续处理循环问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-10-10
  • JFINAL+Ajax传参 array 数组方法 获取request中数组操作

    JFINAL+Ajax传参 array 数组方法 获取request中数组操作

    这篇文章主要介绍了JFINAL+Ajax传参 array 数组方法 获取request中数组操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-08-08
  • springboot注解之@Conditional使用解析

    springboot注解之@Conditional使用解析

    这篇文章主要介绍了springboot注解之@Conditional使用解析,conditional 这个英文单词翻译过来是有条件的,所以 @Conditional 注解是作为条件存在的,如果满足配置的条件则执行,如果没有满足的话就不执行,需要的朋友可以参考下
    2023-11-11
  • java集合类arraylist循环中删除特定元素的方法

    java集合类arraylist循环中删除特定元素的方法

    下面小编就为大家带来一篇Java集合类ArrayList循环中删除特定元素的方法。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2016-11-11
  • spring拓展之如何定义自己的namespace

    spring拓展之如何定义自己的namespace

    这篇文章主要介绍了spring拓展之如何定义自己的namespace方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-09-09
  • Java 反转带头结点的单链表并显示输出的实现过程

    Java 反转带头结点的单链表并显示输出的实现过程

    这篇文章主要介绍了Java 反转带头结点的单链表并显示输出,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-11-11
  • maven搭建spring项目(图文教程)

    maven搭建spring项目(图文教程)

    下面小编就为大家带来一篇maven搭建spring项目(图文教程)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-06-06
  • JavaWeb 简单分页实现代码

    JavaWeb 简单分页实现代码

    这篇文章主要介绍了JavaWeb 简单分页实现代码的相关资料,需要的朋友可以参考下
    2016-11-11
  • 基于springboot的flowable工作流实战流程分析

    基于springboot的flowable工作流实战流程分析

    这篇文章主要介绍了基于springboot的flowable工作流实战流程分析,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-10-10
  • Java递归模糊查询文件实例代码

    Java递归模糊查询文件实例代码

    递归算法是一种直接或间接地调用自身的算法,在计算机编写程序中,递归算法对解决一大类问题是十分有效的,它往往使算法的描述简洁而且易于理解,这篇文章主要给大家介绍了关于Java递归模糊查询文件的相关资料,需要的朋友可以参考下
    2021-11-11

最新评论