Analyze Thread Backlog via Thread-dump
原因:JVM 线程积压,导致服务不可用
排查过程:
总体思路是,找到异常线程,排查下异常线程中不正常的地方。
具体步骤如下:
top -Hp {java-pid}
发现只有几个线程处于 RUNNABLE, 300+ 的线程在 Sleeping
top -b -Hp {java-pid} > threads.top
把所有 JVM 进程内的线程导出到文件
将文件按照 TIME+ (线程累计使用的 CPU 时间)排序
找到其中占用 CPU 时间较长的某个线程 ID,如 23647
, 通过转化为 16 进制 0x5c5f
。
到这里定位到可能出现问题的线程编号 0x5c5f
.
通过 kill -3 {java-pid}
捕捉当前系统运行的线程堆栈。
然后分析 thread_dump.out
发现这个线程被阻塞,阻塞的原因,是因为在等待锁的释放。
怀疑是因为这个锁导致的线程积压。
1 |
|
可以看到有一大片的僵死进程,可以确认问题基本是在这个地方。
那我们在找一下死锁的线程堆栈
通过线程堆栈,大致可以分析出,是 Apache Tiles 在解析 tiles 模板 {name}.xml
时的 DTD 文件时,因为 Socket 一直没有返回,导致锁一直没有被释放。
科普:
HttpURLConnection
是基于HTTP
协议的,其底层通过Socket
通信实现。如果不设置超时(timeout),在网络异常的情况下,可能会导致程序僵死而不继续往下执行。
charles 调试, 本地 DTD 引用 等
Analyze Thread Backlog via Thread-dump
http://kenneth-hao.github.io/2019/09/16/threads-backlog-dump-analyze(ing)/