项目定时任务未按时执行,项目中多处使用@Scheduled实现定时执行,项目上线后一直运行稳定,近期忽然出现定时任务未按时执行。
排查步骤:
① 查看日志,观察到在执行其中一个定时任务时,任务只走了一半,就没有执行记录了;无报错无异常信息(由于@Scheduled默认单线程执行,故此猜测可能是线程阻塞或者意外死亡)
② 查询线程堆栈信息,查看线程状态;
首先查询进程pid
ps -ef|grep jar包全名 # 查看进程pid
然后查询线程堆栈
jstack pid # 查看线程堆栈信息
看到线程状态一直为runnable,进入假死状态,判断线程应该时阻塞了,线程一直卡在WarnDataTimer的1043行处,查看代码此处为请求第三方接口;
③ 写代码测试第三方接口发现在请求时,执行请求接口的时候,会出现第三方接口一直连接不上的情况,由于RestTemplate继承HttpAccessor,连接超时为-1,也就是没有超时时间,会一直等待连接,导致线程阻塞无法往下执行。
处理办法自定义一个连接工程
SimpleClientHttpRequestFactory clientFactory = new SimpleClientHttpRequestFactory();
clientFactory.setConnectTimeout(10); //建立连接的超时时间 5秒
clientFactory.setReadTimeout(10); // 传递数据的超时时间(在网络抖动的情况下,这个参数很有用)
RestTemplate restTemplate = new RestTemplate(clientFactory);
捕获一下异常RestClientException