java.lang.Thread.State: TIMED_WAITING (parking)
背景:项目中突然发现某接口调用出现经常性超时,且后台日志无明显异常,查看代码后发现代码中创建了一个线程池。
解决方案
- 查看堆栈信息并通过在线工具进行分析
jstack -l [pid] >D:\dump.txt
在线分析工具:https://fastthread.io/
- 分析线程堆栈信息,发现线程都处于 TIMED_WAITING (parking) 的阻塞状态,结合堆栈信息可以发现终极原因是获取不到数据库连接
"executor-pool-7" #47116 prio=5 os_prio=0 tid=0x000000002371d000 nid=0x1b24 waiting on condition [0x0000000037d3e000]
java.lang.Thread.State: TIMED_WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x0000000081673d98> (a java.util.concurrent.SynchronousQueue$TransferQueue)
at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:215)
at java.util.concurrent.SynchronousQueue$TransferQueue.awaitFulfill(SynchronousQueue.java:764)
at java.util.concurrent.SynchronousQueue$TransferQueue.transfer(SynchronousQueue.java:695)
at java.util.concurrent.SynchronousQueue.poll(SynchronousQueue.java:941)
at com.zaxxer.hikari.util.ConcurrentBag.borrow(ConcurrentBag.java:157)
at com.zaxxer.hikari.pool.HikariPool.getConnection(HikariPool.java:179)
at com.zaxxer.hikari.pool.HikariPool.getConnection(HikariPool.java:161)
at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:100)
Locked ownable synchronizers:
- <0x00000000da478e18> (a java.util.concurrent.ThreadPoolExecutor$Worker)
- 数据库连接
【1】连接不足,扩大连接数(但一般治标不治本)
【2】分析连接占用情况
【2.1】查看sql连接状态看,查看慢连接
- show PROCESSLIST
- mysql_slow…log
【2.2】执行sql后没能释放连接
- 经过慢日志发现,连接都卡在了某一张表中,最后发现该表已经有2w条数据,添加上索引后恢复正常