服务在线上运行一段时间后,新请求不能被执行,于是猜测问题可能是"任务堆积在线程池中未被执行"。
为了证实猜测是对的,于是紧急写了一个接口用于查看现场池状态,包括监控线程队列,当前任务数,正在执行任务数,以及任务完成数。
"taskCount": 0,
"queueSize": 0,
"activeSize": 0,
"completedTaskCount": 0
问题再次出现时,调用线程池监控接口,发现任务确实堆积在activeSize中,completedTaskCount不在变化。
由于已经明确任务是堆积在活跃线程中,一直没有执行完成,于是联系运维,通过jstack查看线程池日志。
分析出,任务主要阻塞在http调用某个接口
发现服务在调用某个接口时当前服务设置的超时时间未生效,改造httpTemplate,使超时时间生效,并根据以往请求接口的响应时间,设置超时时间为8秒。
1、线程池监控
从线程池监控中看出,任务主要堆积在ip为“127.0.0.1”这台服务的阻塞队列中,在14:10分下线后,经过一个小时的时间,在没有新请求打进14服务器的同时,
阻塞队列的任务并没有被消费。
2、任务堆积分析
从1中可以看出,核心线程一直处于running状态,也就是说6个核心线程被死锁了或者一直在死循环中。
3、找问题突破点
解决问题的突破点在于找出一直处在核心线程中的6个任务,通过日志分析这6个任务执行的最后位置。
4、排查思路
通过jstack日志分析线程池中线程阻塞原因。
通过分析降级的id数据来找出最先进入核心线程并且未被释放的任务。
5、日志优化
继续日志优化,打进的请求要加上线程池信息。为以后出现问题时提供排查路径。