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内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • springboot ElasticSearch如何配置自定义转换器ElasticsearchCustomConversions

    springboot ElasticSearch如何配置自定义转换器ElasticsearchCustomConver

    这篇文章主要介绍了springboot ElasticSearch如何配置自定义转换器ElasticsearchCustomConversions问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-08-08
  • Springboot实现发送邮件

    Springboot实现发送邮件

    这篇文章主要为大家详细介绍了Springboot实现发送邮件功能,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-10-10
  • SpringBoot一个接口多个实现类的调用方式总结

    SpringBoot一个接口多个实现类的调用方式总结

    这篇文章主要介绍了SpringBoot一个接口多个实现类的调用方式,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2024-01-01
  • Java线程等待用法实例分析

    Java线程等待用法实例分析

    这篇文章主要介绍了Java线程等待用法,结合实例形式分析了obj.wait()实现线程等待相关原理与操作技巧,需要的朋友可以参考下
    2018-09-09
  • Java中序列化与反序列化的定义及代码示例

    Java中序列化与反序列化的定义及代码示例

    序列化是将对象状态转换为可存储或传输格式的过程,反序列化则是将存储或传输格式恢复为原始对象的逆过程,这篇文章主要介绍了Java中序列化与反序列化的相关资料,需要的朋友可以参考下
    2024-10-10
  • JAVA操作MongoDB数据库实例教程

    JAVA操作MongoDB数据库实例教程

    MongoDB是一个文档型数据库,是NOSQL家族中最重要的成员之一,下面这篇文章主要给大家介绍了关于JAVA操作MongoDB数据库的相关资料,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2023-05-05
  • Java设计模式之备忘录模式(Memento模式)介绍

    Java设计模式之备忘录模式(Memento模式)介绍

    这篇文章主要介绍了Java设计模式之备忘录模式(Memento模式)介绍,memento是一个保存另外一个对象内部状态拷贝的对象,这样以后就可以将该对象恢复到原先保存的状态,需要的朋友可以参考下
    2015-03-03
  • Java数组转List及Stream的基本方法使用方法

    Java数组转List及Stream的基本方法使用方法

    Java 的 Stream 流操作是一种简洁而强大的处理集合数据的方式,允许对数据进行高效的操作,如过滤、映射、排序和聚合,这篇文章主要介绍了Java数组转List及Stream的基本方法使用教程,需要的朋友可以参考下
    2024-08-08
  • SpringWebMVC的常用注解及应用分层架构详解

    SpringWebMVC的常用注解及应用分层架构详解

    这篇文章主要介绍了SpringWebMVC的常用注解及应用分层架构,SpringWebMVC是基于ServletAPI构建的原始Web框架,从⼀开始就包含在Spring框架中,感兴趣的朋友可以参考下
    2024-05-05
  • 深入学习Java同步机制中的底层实现

    深入学习Java同步机制中的底层实现

    在多线程编程中我们会遇到很多需要使用线程同步机制去解决的并发问题,这些同步机制是如何实现的呢?下面和小编来一起学习吧
    2019-05-05

最新评论