首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >线程泄漏(2)-之httpclient使用不当

线程泄漏(2)-之httpclient使用不当

作者头像
用户12591013
发布2026-07-10 15:29:50
发布2026-07-10 15:29:50
60
举报

又一次线上救火,线上再次发生线程数暴涨,且无法回收,本文记录问题发现解决的全过程。

图片
图片

问题说明

某系统内存使用过大,并发现线程数很高,有一万多个(通过监控系统就可以发现,细节此处不赘述)。

图片
图片

详细排查过程

  • step1.找到数目最多的线程 使用arms 的应用诊断->线程分析,找到数目最多的线程。

说明:也可以使用jdk命令,获取thread dump信息,使用命令简单处理,即可获得数量最多线程。

代码语言:javascript
复制
jstack 1 > thread.dump // 1 为java进程id, 重定向到thread.dump文件

cat thread.dump|grep tid|sort //过滤tid,并排序
  • step2. 查看方法调用栈 通过thread dump 文件找到idle-connection-evictor-* 线程的调用栈,如下:
代码语言:javascript
复制
"idle-connection-evictor-1" #941 daemon prio=5 os_prio=0 cpu=0.77ms elapsed=202.60s tid=0x00007f78ec521750 nid=0x3af waiting on condition  [0x00007f787d574000]
   java.lang.Thread.State: TIMED_WAITING (sleeping)
        at java.lang.Thread.sleep(java.base@17/Native Method)
        at java.lang.Thread.sleep(java.base@17/Thread.java:337)
        at java.util.concurrent.TimeUnit.sleep(java.base@17/TimeUnit.java:446)
        at org.apache.hc.core5.util.TimeValue.sleep(TimeValue.java:323)
        at org.apache.hc.client5.http.impl.IdleConnectionEvictor$1.run(IdleConnectionEvictor.java:62)
        at java.lang.Thread.run(java.base@17/Thread.java:833)

分析上面的调用栈,第7行,可见问题来自httpclient5的IdleConnectionEvictor类。

  • step3. IDE 打开pom,找到httpclient5的依赖yidun-java-sdk
  • step4. 找到业务使用代码: 业务代码,引入httpclient

底层代码,设置线程池

代码分析

每次执行方法,都会创建一个httpclient,且第三方工具,未提供close方式,不能将httpclient 关闭(httpclient里面有一个叫做ideConnectionEvitor的类,它有一个thread),这样就造成每次执行都会生成一个名字为idle-connection-evitor-1的thread,且不会被释放。

  • step5.修正

按照appid将httpclient缓存起来,每次都执行同一个httpclient。

图片
图片

套路总结

遇到线程数过多,排查套路如下:

1.先找到数目最多的线程

可以通过arms(公司使用的阿里云监控系统--读者可结合自己公司实际情况)去找,如果arms不好用,请运维同学执行一下jstack,把线程dump出来

代码语言:javascript
复制
jstack pid|grep tid|sort // pid 是java进程的id

2.再找到线程栈信息,找到调用链路,确认业务代码。

如果线程栈里面显示的是调用的root方法,不是业务方法,可以先找到对应的class,再确认上层调用。本文中,root方法是thread.sleep(), 不能确定业务方法,但是没关系,我们找到了httpclient5,根据pom依赖,又找到了上层调用是:yidun-java-sdk。

3.根据线程名字等信息,找到对应的thread,再结合业务情况判断修改。

找到线程的名字,再根据线程的名字定位到代码,是发现问题的关键!所以写多线程的代码,使用线程池,务必要指定线程池的名字,不能使用默认的名字,因为一个有意义的名字可以就可以给排查工作节省大量的时间!

4.务必注意httpclient的使用方式,要么关闭,要么缓存

图片
图片
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2025-12-30,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 鹏哥调优笔记 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 4.务必注意:httpclient的使用方式,要么关闭,要么缓存。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档