Spring redis使用报错Read timed out排查解决

文章目录

使用场景

  • 我们使用redis作为缓存服务,缓存一些业务数据,如路口点位信息、渠化信息、设备信息等
  • 有一些需要实时计算的数据,缓存在redis里,如实时信号周期相位、周期内过车数量等
  • 有需要不同服务访问的数据,使用redis作为共同可访问操作的缓存空间

报错信息

  • 在数据库数据变动时,需要清楚redis里的缓存,等下次查询需要时从数据库查询,再写入redis

  • 此时删除数据报错,核心报错信息Read timed out,连接超时

  • 检查了下,redis服务正常

  • 具体报错信息,分两个时间点的报错,(截取部分)如下:

  • 报错日志一JedisConnectionException:

    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)

  • 报错日志二 Error while validating pooled Jedis object:

    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)

解决方式

  • 报错信息很明显,"Read timed out"超时错误,通常会有以下几种可能:
  • 1、Redis服务端问题导致无法连接或连接出现问题,可以通过检查Redis服务端日志或查看Redis服务器状态来确认
  • Redis未正常在运行,异常终止,或者启动失败
  • 未正确在程序里配置连接ip端口参数,例如ip错误使用localhost,又不在一台机器上
  • 2、 网络连接不稳定或延迟导致Redis连接超时。可以尝试更改网络环境或增加Redis客户端连接超时时间。
  • 检查程序服务于redis之间的网络是否联通,是否存在明显延迟
  • 可以修改Spring redis配置参数,增加连接超时时间
    1. Redis服务器负载过高或使用Redis的其他应用程序占用了太多的资源,导致Redis无法响应请求。可以通过检查Redis服务器的负载或性能参数来确定是否存在此问题。
  • 检查服务器情况,确保内存和磁盘空间充足,检查已使用内存、剩余内存、已使用磁盘、剩余磁盘等
  • 简单来说,你的服务对redis的使用频率,如果读写很高很频繁、数据内容很多,就提供比较好的服务器,或者搭建redis集群
  • 也可以优化Spring redis配置参数,增加最大线程数、空闲线程数、连接超时时间等
    1. 应用程序本身存在性能瓶颈或异常,导致Redis的操作时间过长。可以检查应用程序代码和运行日志,查找可能导致性能问题的因素
  • 如果比较大的集合对象在redis存取,会占用很多内存,高并发情况下,可能做不到及时响应,可以只缓存必要的字段属性
  • 大量的key值,同时加到redis里面,又在一段时间后同时失效,造成瞬时压力过大,这要在业务上做一些随机失效时间
  • 针对以上情况,我们可以使用不同的解决方法来解决问题。例如,可以优化Redis服务器的配置和设置,更改Redis客户端连接超时时间,或调整应用程序性能等。
  • 我们此次检查后的改动如下:
yml 复制代码
spring:
  redis:
    jedis:
      pool:
        min-idle: 10
        max-idle: 300  # 改大了
        max-wait: 30000  # 改大了
        max-active: 200  # 改大了
  • 对应到我们的docker-compose.yml
yml 复制代码
  core-app:
    image: june
    container_name: core
    volumes:
      - /etc/localtime:/etc/localtime
    depends_on:
      - postgresql
      - redis
    environment:
      - _JAVA_OPTIONS=-Xmx6G -Xms1G
      - SERVER_PORT=8181
      - SPRING_PROFILES_ACTIVE=prod,api-docs,no-liquibase
      - SPRING_DATASOURCE_URL=jdbc:postgresql://postgresql:5432/core
      - SPRING_DATASOURCE_USERNAME=xxxx
      - SPRING_DATASOURCE_PASSWORD=xxxxxxx
      - SPRING_REDIS_HOST=redis
      - SPRING_REDIS_PASSWORD=xxxxxxxx
      - spring_redis_jedis_pool_maxIdle=300 # redis配置
      - spring_redis_jedis_pool_maxWait=30000
      - spring_redis_jedis_pool_maxActive=200
    restart: on-failure
相关推荐
Flittly9 小时前
【AgentScope Java新手村系列】(16)从RAG到多路检索
java·spring boot·spring
咖啡八杯1 天前
GoF设计模式——中介者模式
java·后端·spring·设计模式
用户3074596982072 天前
Redis 延时队列详解
redis
烤代码的吐司君2 天前
Redis 数据结构 ZSet, BIT, HyperLogLog,Geo 空间数据
redis·后端
Flittly3 天前
【AgentScope Java新手村系列】(14)人机交互
java·spring boot·spring
leeyi5 天前
Checkpoint 机制:Agent 怎么在断电后接着跑
redis·aigc·agent
云技纵横6 天前
一个 @Async 让循环依赖暴雷:Spring 代理的暗坑
redis
犯困蛋挞yy6 天前
用Claude快速解决Redis代码报错反复无解的问题
redis
唐青枫7 天前
Java Spring WebFlux 实战指南:用 Mono、Flux 和 WebClient 写响应式接口
java·spring
咖啡八杯8 天前
GoF设计模式——策略模式
java·后端·spring·设计模式