spring boot中得定时任务执行一段时间后突然停了 排查过程

版权声明: https://blog.csdn.net/qq_32157851/article/details/84870403

在spring boot 项目中设置了一些定时任务,前几天还执行得好好的,突然有一天就不再执行了,基本上呢都是执行了四天左右,定时任务停掉不在运行了,然后重启程序定时任务就好使了,出现这么两次,第三次是在重启以后第三天出现定时任务不再执行。感觉莫名其妙,查了好多资料,以下是关于我查到的关于定时任务突然停掉的一些原因。

1)首先查到了大部分经验说是spring boot中得定时任务都时单线程得,要进行多线程执行,还要配置

2)如果线程本身出现死锁,ExecutorService一般不会监控到并处理的,所以它会将后续的定时计划全部delay和pending。

3)如果线程的某次定时执行过程中出现了未捕获的异常,那么ExecutorService也会将后续的定时计划全部delay和pending。

4)定时任务执行成功了,于是得出结论: 服务器系统时间改变后,Spring 定时任务将失效。

5)另外,排查上述的问题也比较简单,只要每次定时任务执行时打一条log,并在task的最外层捕获所有Throwable并log就行了
如果你在多个函数上使用了@Scheduled,那么一定是一个执行完毕,才能排下一个。这往往不是我们想要的效果。

6) 和远程服务间创建的keep alive的connection过多,导致后面创建的连接会一直连接超时,导致线程出现异常。

7) http请求出现某种错误时,http请求僵死,导致线程也不再往下执行。最终导致后面的定时任务也不再执行。
  之前一直认为http会有一个默认的超时时间(可能是5min),超过这个时间后会报超时异常。这个看法误导了我。

第一条,我一开始还真以为是单线程得,以为就是这个原因,也没有测试,因为项目中确实只有通过@EnableScheduling 这个注解开启定时任务得,然后定时任务的方法上使用@Scheduled(cron = "0 0 1 1 * ?")   或者@Scheduled(fixedRate = 1000 * 60 * 5)这样得策略执行,但是主管说然我测试一下是否为单线程执行,感觉springboot 不能这么low,最后测试的结果确实不是单线程执行得,是多线程执行得,所以这个原因就pass掉了

第二条,我也不知道怎么才能出现死锁,感觉模拟不来,就先搁下了,查看后面得原因是否与我出现的一样

第三条,与我的情况一样,定时任务在执行最后几次都是正常的,但是突然之间就停掉了,任何报错都没有,什么异常都没有捕获到,所以我觉得我的定时任务应该是没有捕获到异常导致所有的其他定时任务也执行不下去。但是怎么解决呢?继续查找下去。

第四条、经过反复查看,服务器的时间是没有改变得,和这个没有关系(我是查看服务器时间没有变化太大,没有变成其他时区确定)

第五条、这是一条然你发现定时任务执行到哪一步就不再继续往下执行,所以我项目中打了很多log,因为定时任务都是去请求其他平台,所以我在本地获取数据那打了一条log,在请求完接口返回数据那又打了一条log,通过两次得定时任务停止,可以看到最后一次定时任务之情本地获取数据结果,并没有返回数据结果,也没有抛异常,我的try()catch{ }在整个得请求接口代码中。所以感觉第二条估计是我的病症所在。

第六条和第七条其实是关于上面我的病症解释和解决

一直奇怪为什么会出现调用的平台的结果没有返回而没有抛异常,定时任务就不再执行下去了呢?终于查看到了下面这篇博客

https://www.cnblogs.com/zj0208/p/7018098.html  也就是第六条和第七条。(但是这里我也了解到了我代码中请求的另一个平台在这段时间内确实服务有挂掉或者重启等操作)

查看请求其他平台的得方法,发现是通过httpclient请求的,网上找到了关于HTTP请求时connectionRequestTimeout 、connectionTimeout、socketTimeout三个超时时间的设置。下面这个链接

https://blog.csdn.net/wangjin890620/article/details/54630219

现在刚改代码,重新启动了,等几天看看定时任务还会停掉吗?如果没有再停掉,就说明确实是连接没有超时所导致得。

------------------------下面也是我找到的一些排查问题-------------------------------

https://blog.csdn.net/stationxp/article/details/80683968

由于httpclient自己没有默认超时时间的设置,当开发人员没有设置超时间是的时候,在server的服务端网络出现问题或者一直不返回给客户端数据结果,就发现client端的请求线程一直卡住不会释放,如果这个是线程池中的线程,就会一直占用线程池资源,导致线程池不能响应后续的的任务。

 

静候佳音中!!!!!!!!

猜你喜欢

转载自blog.csdn.net/qq_32157851/article/details/84870403
今日推荐