定时任务卡死问题排查

背景描述:使用quartz建立多个定时任务,每5分钟执行一次。定时任务中包含httpclient的网络访问,及druid的数据库访问。执行一段时间后不定期(可能10天半个月,可能好几个月)卡死。
表现状况为:

  • 日志到某个时间点突然没有输出了,也没有异常日志记录,排除当时磁盘空间不足的问题

  • httpclient使用的4.3版本,出问题的生成环境下已在request中设置3种超时时间。实际测试中除了setConnectTimeout与setConnectionRequestTimeout即使不设置,程序也会抛出超时异常。只有当setSocketTimeout不设置的时候,程序会出现日志不打印一直卡死的状况,但与我要解决的问题来看还是有略微区别。当时的内存状况不一致。(图1为生产环境上卡死时的内存,图2为本机测试时,故意不设置setSocketTimeout超时情况下的内存图 )
    blob.jpg(图1)blob.jpg(图2)

  • 生成环境下设置了数据库超时,本机测试时暂时还没有测试数据库超时的情况。

下次生成环境上再发生此类状况的排查步骤:

  1. 本机打开jdk安装目录下的visualVM查看线程执行情况,正常定时任务执行时线程应该是如下图的少量runnalbe,如图1所示,但是本机测试时,故意让服务器端下断点不返回信息,在客户端的httpclient中不设置setConnectTimeout超时时间,最终显示的线程图样是一直runnalbe的,因此下次在生产环境下出现这个问题时,可以查看线程中,该线程是否一直是runnalbe状态如图2所示
    blob.jpg(图1) blob.jpg(图2)
  2. 使用jstack查看当时的业务定时任务线程中具体代码。打开步骤,找到程序对应的pid,然后使用命令jstack 程序pid的方式查看线程状态(图1)。 使用jstack的原因是这个可以看到具体代码,如图2
    blob.jpg(图1)blob.jpg(图2)

今天又发生了一次,排查怀疑是数据库连接未释放造成的。

blob.jpg
(发生问题的机器上,线程图。从中可以看到执行定时job的线程pool-3-thread-1一直在运行,类似于之前在本地机器上模拟的httpclient未设置响应时间的状态)

blob.jpg
(发生问题的机器上,内存图)


原文地址:https://www.cnblogs.com/falcon-fei/p/11060174.html