V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Sponsored by
LinkedIn
2000 个不用坐班的远程好工作在召唤你 · 弹性上班不打卡,工作和生活都能拥有
2000 个不用坐班的全球远程工作,帮助 V2EX 的小伙伴开启全新的工作方式。
Promoted by LinkedIn
hello826
V2EX  ›  程序员

Java 线程数过高,如何排查

  •  
  •   hello826 · 2021-01-06 14:33:53 +08:00 · 1905 次点击
    这是一个创建于 626 天前的主题,其中的信息可能已经有所发展或是发生改变。

    最近在生产环境遇到个问题,一个 java web 服务的监控到线程数达到 4000 多左右,而且一直在上涨。

    通过 jstack 查看线程情况,发现状态都是 TIMED_WAITING,

    但是看堆栈信息只能看到很少的信息,无法定位到是哪个地方导致的,调用信息如下图,我怀疑是项目用到了

    httpClient 导致的(版本 4.3 ),但是没有证据。。。请问下各位有什么好的方法能定位到具体是哪块调用的方法导

    致的。

    jstack 分析结果如下,堆栈信息很简单,4000 多个都是和这个一样的情况 result.png

    14 条回复    2021-01-07 18:38:14 +08:00
    BBCCBB
        1
    BBCCBB  
       2021-01-06 14:38:07 +08:00   ❤️ 2
    首先代码里生成 thread 的地方一定要指定 name/threadFactory, 不然不好排查..
    chendy
        2
    chendy  
       2021-01-06 14:48:04 +08:00
    这个线程名是手 new Thread 的线程名
    找到 new Thread 的地方,修改成使用线程池的形式
    代码里搜 new Thread( 基本就能找到了……
    leafre
        3
    leafre  
       2021-01-06 14:50:57 +08:00
    写业务时没命名好线程的结果
    cheng6563
        4
    cheng6563  
       2021-01-06 14:51:17 +08:00
    大概率是监控程序起了个线程想异步推送数据,但没有设置超时时间,目标端口能握手但不响应(多半是安全组或防火墙没开),就出现这样的情况了。
    你看看能不能配置下响应超时时间,也可以排除下那个监控服务端的连接问题。
    Jooooooooo
        5
    Jooooooooo  
       2021-01-06 14:52:11 +08:00
    ali 的 Java 开发规范大部分内容遵守都是不错的

    比如这个, 线程名称要自定义
    securityCoding
        6
    securityCoding  
       2021-01-06 14:53:59 +08:00
    直接搜业务代码 Thread 关键字
    sonice
        7
    sonice  
       2021-01-06 15:19:26 +08:00
    Unirest 没 shutdown
    ChovyChu
        8
    ChovyChu  
       2021-01-06 16:01:38 +08:00
    看一下栈不就知道这个线程是干嘛的吗,一下就能找到在哪创建的了吧
    lsongiu
        9
    lsongiu  
       2021-01-06 17:31:19 +08:00
    客户端大量关闭 tcp 链接,time_wait 过多?短连接改长连接试试?不行来个 http 连接池
    berg223
        10
    berg223  
       2021-01-07 00:38:15 +08:00
    原因是你 new 的 unirest 实例太多了,具体参见:
    https://stackoverflow.com/questions/59309046/unirest-thread-leak
    berg223
        11
    berg223  
       2021-01-07 00:41:20 +08:00
    其实堆栈信息已经很明确了,就是卡在了 SyncIdleConnectionMonitorThread 这个文件的 22 行,你看一下代码差不多能猜到原因了
    berg223
        12
    berg223  
       2021-01-07 00:45:53 +08:00
    具体的讨论可以看一下: https://github.com/Kong/unirest-java/issues/140
    hello826
        13
    hello826  
    OP
       2021-01-07 09:59:03 +08:00
    @berg223 果然是这个,我还以为是 jdk 的方法,没想到这个是二方的包
    hello826
        14
    hello826  
    OP
       2021-01-07 18:38:14 +08:00
    问题解决了,不是 httpClient 的锅,是二方包的 bug,文件服务上传每次前端有请求,后端都会创建一个线程,而且是永不关闭的线程。。
    关于   ·   帮助文档   ·   API   ·   FAQ   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   2379 人在线   最高记录 5497   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 316ms · UTC 05:00 · PVG 13:00 · LAX 22:00 · JFK 01:00
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.