当前位置: 首页 > article >正文

JedisException:Could not get a resource from the pool

一、问题描述

最近一个老项目线上出现一个问题,操作 redis 的地方全都报错

org.springframework.data.redis.RedisConnectionFailureException: Cannot get Jedis connection; nested exception is redis.clients.jedis.exceptions.JedisException: Could not get a resource from the pool
at org.springframework.data.redis.connection.jedis.JedisConnectionFactory.fetchJedisConnector(JedisConnectionFactory.java:281)
at org.springframework.data.redis.connection.jedis.JedisConnectionFactory.getConnection(JedisConnectionFactory.java:464)
at org.springframework.data.redis.cache.DefaultRedisCacheWriter.execute(DefaultRedisCacheWriter.java:238)
at org.springframework.data.redis.cache.DefaultRedisCacheWriter.get(DefaultRedisCacheWriter.java:109)
at org.springframework.data.redis.cache.RedisCache.lookup(RedisCache.java:82)
at org.springframework.cache.support.AbstractValueAdaptingCache.get(AbstractValueAdaptingCache.java:58)
at org.springframework.cache.interceptor.AbstractCacheInvoker.doGet(AbstractCacheInvoker.java:73)
at org.springframework.cache.interceptor.CacheAspectSupport.findInCaches(CacheAspectSupport.java:554)
at org.springframework.cache.interceptor.CacheAspectSupport.findCachedItem(CacheAspectSupport.java:519)
at org.springframework.cache.interceptor.CacheAspectSupport.execute(CacheAspectSupport.java:401)
at org.springframework.cache.interceptor.CacheAspectSupport.execute(CacheAspectSupport.java:345)
at org.springframework.cache.interceptor.CacheInterceptor.invoke(CacheInterceptor.java:61)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:688)

Caused by: redis.clients.jedis.exceptions.JedisException: Could not get a resource from the pool
at redis.clients.util.Pool.getResource(Pool.java:51)
at redis.clients.jedis.JedisSentinelPool.getResource(JedisSentinelPool.java:210)
at redis.clients.jedis.JedisSentinelPool.getResource(JedisSentinelPool.java:17)
at org.springframework.data.redis.connection.jedis.JedisConnectionFactory.fetchJedisConnector(JedisConnectionFactory.java:271)
… 89 common frames omitted
Caused by: java.util.NoSuchElementException: Pool exhausted
at org.apache.commons.pool2.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:456)
at org.apache.commons.pool2.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:365)
at redis.clients.util.Pool.getResource(Pool.java:49)
… 92 common frames omitted

二、问题排查

看报错,感觉是连接池资源耗尽了,看了下配置,最大连接数配的128,然后有四台服务器,不觉得是配少的原因,所以怀疑是连接池资源使用后未释放,但是看了下代码,都是直接用 redisTemplate 操作的,不存在自己操作资源,因为是老项目,使用的版本都比较低,于是怀疑是不是 Jedis 的bug,这边使用的是 Jedis 的 2.9.1 版本,在网上搜了之后,发现确实存在bug,参考:https://github.com/redis/jedis/issues/1920

image-20241112103747014

image-20241112103757930

image-20241112103845312

意思就是:

1、当线程A在 Jedis 类中操作到 returnResource,还没执行到 this.dataSource = null;

2、线程B在 JedisSentinelPool 类里执行到 jedis.setDataSource(this);

3、这时候线程A执行了 this.dataSource = null;

4、这时候线程B里的 dataSource 就是null了,当线程B执行到 Jedis 类里的 close 方法时,就永远不会走到 returnResource

这就导致在高并发的时候,有可能存在线程资源没有正常的回收,长时间运行下来,线程池中可用的资源会越来越少,最终导致没有资源可用,我们这个老项目服务确实有大半年没有重启了,符合这个场景

Jedis在 2.10.2 版本对 Jedis 类的 close 方法做了修改,解决了这个问题

image-20241112105224640

三、解决问题

升级 Jedis 的版本到2.10.2


http://www.kler.cn/a/390146.html

相关文章:

  • 《MYSQL45讲》kill不掉的线程
  • 深入探讨 MySQL 配置与优化:从零到生产环境的最佳实践20241112
  • 实验一:自建Docker注册中心
  • 记录学习react的一些内容
  • MySQL:CRUD
  • 【2024最新】基于springboot+vue的闲一品交易平台lw+ppt
  • SpringCloud 微服务消息队列灰度方案 (RocketMQ 4.x)
  • SQL 窗口函数
  • 什么是C/C++,有什么特点
  • 物联网学习路线来啦!
  • 道可云人工智能元宇宙每日资讯|2024国际虚拟现实创新大会将在青岛举办
  • cache写策略 操作系统
  • nginx 部署2个相同的vue
  • 241111.学习日志——【CSDIY】Cpp零基础速成
  • 2024年11月10日系统架构设计师考试题目回顾
  • 【算法速刷(9/100)】LeetCode —— 42.接雨水
  • 2024年9月青少年软件编程(C语言/C++)等级考试试卷(四级)
  • flask logger 使用 TimedRotatingFileHandler 报错 PermissionError 另一个程序正在使用此文件
  • NVR录像机汇聚管理EasyNVR多品牌NVR管理工具/设备:大华IPC摄像头局域网访问异常解决办法
  • 哪家云服务器好跑AI?瞄准AutoDL(附NVIDIA GPU 算力排名表)
  • Linux基础之病毒编写
  • Docker 操作指令
  • 如何设置el-date-picker的默认截止时间为“23:59:59”
  • 故事121
  • Ceph MDS高可用架构探索:从零到一构建多主一备MDS服务
  • (Go基础)Go的运行流程步骤与包的概念