两次连接池泄露的BUG

问题1

现象

1、WEB服务发版不报错,但运行一段时间后,服务假死,请求卡住,需要重启才能解决;

排查过程

1、重启,恢复正常,但过几个小时又复现,确定不是偶现BUG; 2、在再次复现的时候,打印线程日志,是否线程耗尽;

bash 复制代码
jstack <pid> > /tmp/thread.log

3、让运维重启,先让服务正常,开发同步分析BUG产生原因;

4、排查发现,新增代码有很多WAITING,等待线程连接,猜测是否是线程池未回收,导致WEB线程一直卡住,后面WEB线程池耗尽的问题;

5、排查代码,使用了JedisConnectionFactory对象获取连接,为了使用eval,需要jedis对象,这种获取对象的方式,需要手动归还连接,close(还回连接池);

6、更新代码,重新发版,bug不在出现,问题解决;

问题2

现象

1、服务发版,多个节点都正常,但突然有一个节点出现了Redis连接变成了9500多报警,还一直不能降下去;

排查过程

1、排查是否真的有这么多连接,是否是监控误报,登录Redis,查看connected_clients数量,确实是9500多;

bash 复制代码
 INFO clients

2、查看连接详情,发现大绝大部分连接是SELECT(切换redis数据库),PING(心跳维持Redis连接,心跳维持连接,就表示创建的连接不会自动关闭,因为做了心跳维持),并且age和idle时间很近,说明连接都是活跃的连接,不是没有用的连接,心跳PING其实也会让连接保持活跃;

bash 复制代码
CLIENT LIST

3、排查为什么会有建立这么多连接,是有代码用了for循环在创建连接吗,不太可能有人这样做,人为无缘无故创建这么多连接,不正常;

4、排查代码,主要是这次发版的几个服务,发现有两种方式创建redis连接池,一种是Spring

Cloud的,默认最大200个,idle最大最小是50个,并且用法就是redisTemplate,这个基本不可能有这种泄露的问题,毕竟是一个这么成熟的开源工具,除非像上面一样用JedisConnectionFactory获取对象,但又不关闭,里面又用了定时任务做redis操作,但这次发版没有修改redis,所以概率太低;

5、再一种情况就是自定义连接池,这也是重点怀疑目标,这个连接池用的最大连接是150,应该也算不到这么大,排查发现写的自定义连接池,是懒加载方式,在使用的时候通过单例调用,但这个连接池是创建之后放入map中,初看没有啥问题,但细看就会发现,如果同时多个获取连接打到了初始化的地方,并且都进入了 inst=null的位置,而初始化过程又是一个比较长的过程,那不就出BUG了;

6、这个连接被网关服务使用,网关服务重启,会有批量设备重连,重新登录需要鉴权,redis,所以会导致创建多个redis连接池,但map覆盖后,实际使用的连接池只有最后一个,但因为连接池设置为维持连接模式,也就是会PING,导致那些覆盖的连接也不会回收,从而触发连接数量暴增问题;

7、调整代码,加锁,重新发版,连接就不会变的这么大,问题解决;

相关推荐
知行合一。。。10 小时前
RAG--03--Milvus基本用法
数据库·oracle·milvus
2601_9620715710 小时前
【Java报错已解决】org.springframework.beans.factory.BeanCreationException
java·开发语言
TDengine (老段)10 小时前
TDengine 线程模型 — 网络、调度、执行
大数据·数据库·物联网·制造·时序数据库·tdengine·涛思数据
zww894911110 小时前
酒馆预约系统开发实战:从需求分析到上线全流程指南
java·eclipse
上学的小垃圾11 小时前
01-数据库系统概述
数据库
二进制漫游记12 小时前
FastAPI项目集成 Qdrant向量数据库+阿里云Embedding完整实战(工具封装+业务调用)
数据库·python·阿里云·embedding
2501_9289962212 小时前
GPT-4o换DeepSeek迁移成本多少?中科热备解析API聚合平台技术账本
前端·数据库·人工智能
zww894911113 小时前
匿名树洞系统开发实战:从需求分析到部署指南
java·eclipse
泡干脆面就番茄14 小时前
MySQL_子查询_分页查询与联合查询详解
数据库·mysql
黑马程序员毕设14 小时前
基于Java的医院药品管理系统的优化设计与实现
java·开发语言·spring boot·小程序·架构·课程设计·毕设