Springboot定时任务不执行了?

Springboot定时任务不执行了?

公司负责维护的项目这两天出了个BUG:某项目的统计报表功能突然停止更新了,数据停留在了八月十七号。领导二话不说找到了我:“kk,最近手里没啥事干吧,把这个问题处理一下!”“好嘞!”就这样,愉快的找BUG的一天开始了。

image

根据我多年以来(并没有)跟BUG战斗的经验,首先第一步就是顺着接口找到项目源码,于是乎我发现这个项目中的定时任务统一放在了一个模块管理,一共有8个定时任务类。

image.png

仔细阅读源码,发现每个定时任务类中的方法都有用日志记录,在方法执行前后都会输出日志。

image.png

看到这里,问题就比较清晰了。如果是定时任务出错了,那么这些没执行的定时任务在日志中都只会输出“任务开始”,而不会输出“任务结束”。 但新的问题冒出来了:什么问题会导致所有定时任务集体扑街?带着这个疑惑,机智的我远程连接线上生产环境机器,进入项目的日志路径,打开了8月17日那天的日志文件。仔细检查后我发现,日志中只有一条定时任务输出了“任务开始”没有输出“任务结束”,而其他的定时任务压根没有开始。

image.png

这就很奇怪了,为什么只执行了一个定时任务?难道这个任务出问题,其他的任务都不执行了吗?

擦了擦额头上的汗,我决定向度娘求助,于是乎我找到了答案。

SpringBoot使用@scheduled定时执行任务的时候是在一个单线程中,如果有多个任务,其中一个任务执行时间过长,则有可能会导致其他后续任务被阻塞直到该任务执行完成。也就是会造成一些任务无法定时执行的错觉。

也就是说,就是因为这一个定时任务没执行成功导致线程阻塞,所以其他定时任务都没法执行!

解决这个问题也很简单,只需要添加一个配置类,将定时任务用线程池管理,允许多线程执行,问题就能解决一大半了。代码如下:

@Configuration
public class ScheduleConfig implements SchedulingConfigurer {
    @Override
    public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
        
        taskRegistrar.setScheduler(Executors.newScheduledThreadPool(5));

    }
}

重启项目,再查看系统,问题解决!

image.png

正当我以为万事大吉时,我突然想到还有个问题没解决:虽说其中一个定时任务执行失败不会影响其他定时任务,但这个出问题的定时任务为啥没执行成功呢?

image.png

得了,搞了半天BUG的根本原因还没解决。但通过这次找BUG的经历,我对spring自带的定时器有了更深的了解,还是有不少收获的。接下来得去好好学习一下这方面的内容。

不说了,继续找BUG单挑去。

(完)

Respect All , Fear None

Copyright: 采用 知识共享署名4.0 国际许可协议进行许可

Links: https://www.keikei.vip/archives/springboot定时任务阻塞问题解决方案