问题:
系统中的计划任务未按照定时时间执行,如下图,计划是设定每天7:50执行,但是上次执行时间是昨天,但是下次执行时间已经到了明天,在计划任务调度日志中也没有查看到当天是运行中的记录,如何针对此类问题进行排查。
跟进排查方案:
1、计划没有按时执行原因大致分为一下几种情况。
情况1:服务器繁忙延期,由于预定时间点服务器线程爆满,会导致计划延期直到服务器空闲时接入;
情况2:重试延期,由服务器执行失败后重试导致与预定时间不符合;
情况3:宕机重启延期,服务器重启后会检查过期计划;
情况4:检查不通过,例如计划处于运行中、计划执行人被禁用等可能性。
2、排查思路:
(1)计划调度日志中查看节点计划任务的调度总数及当前正在执行的计划任务,截图计划任务调度界面(如果是集群环境,需要通过ip逐个访问确认)。
计划调度日志界面显示说明:
runningCount / totalCount 【待执行 waitingCount个】
指标说明: 1、运行中的计划(runningCount): select count(1) from QRTZ_FIRED_TRIGGERS; 2、服务器数量(serverCount): select count(1) from QRTZ_SCHEDULER_STATE where LAST_CHECKIN_TIME + CHECKIN_INTERVAL > unix_timestamp(); 3、每台服务器最大并发数(threadCount): org_quartz_threadPool_threadCount=10 4、totalCount = serverCount * threadCount 当 runningCount >= totalCount ,超载(waitingCount): 5、待执行(waitingCount) select count(1) from QRTZ_TRIGGERS where NEXT_FIRE_TIME < unix_timestamp() and TRIGGER_STATE = 'WAITING';
2、如果出现上图中的【待执行 XX个】,则说明节点计划任务爆满,可能存在运行中的计划任务特别慢或者阻塞队列,需要确认阻塞的计划任务及未执行的计划任务是否处于待执行队列中。
(1)确认阻塞的计划任务:
步骤1:过滤出来运行中的计划任务,确认长时间处于运行中的计划,并获取对应计划的运行节点及计划对应线程号(通常阻塞可能是总的所有线程数都满了处于运行中,需要查看多个):
步骤2:通过ip访问该计划的对应运行节点,进入【系统监控】-【线程】,点击界面上的刷新,根据步骤2中的运行线程搜索,可以将线程复制到文本工具中保存,每间隔一段时间刷新并保存线程执行情况(具体间隔时间根据计划运行中的时长调整,如果计划已经执行几个小时了,可以每间隔5-10分钟刷新一次,获取2-3个线程执行情况)
(2)确认未执行的任务是否处于执行队列中,执行如下SQL,如果可以查询返回即该计划还在排队队列中
select * from QRTZ_TRIGGERS where NEXT_FIRE_TIME < unix_timestamp() and TRIGGER_STATE = 'WAITING' where TRIGGER_NAME like '%计划ID%';
3、计划任务总体情况确认
(1)监控页面(v95以上,buildtime2022-10-01以后)需要管理员权限才能打开(如果环境计划任务总数比较多,页面打开可能会浏览器卡死,修改showAll=false,此时计划任务是分页的,默认只展示10条)
(2)监控页面说明
【节点总览】
注意事项:如果是集群环境,如上图interval不能超过7500,即时间差不能超过7.5s,超过这个时间范围就有可能出现计划无法按时执行的各种问题,需要先实现集群环境操作系统的服务器时间同步(需要配置一个时间标准服务器,然后再配置其他服务器跟这个时间标准服务器同步时间),如网络参考文档:内网环境的NTP服务搭建和应用(实现各服务器时间同步)
【计划表】
如果怀疑只是某个计划没执行,也可以拿到计划名称,在上述计划表拿到c_scheduleid(计划ID),然后需要在最下方的qrtz_triggers中找到对应的记录