我是靠谱客的博主 傲娇悟空,最近开发中收集的这篇文章主要介绍quartz在用mysql做持久化有时候会错过调度的问题,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

之前做的一个用quartz调度周期任务的系统,我在测试的时候偶然发现quartz有时会错过第一次触发(当时我设置的是每分钟执行一次,开始时间在添加进quartz的时间之前),我找了很多博客论坛,也在百度和Stack Overflow搜索,但都没有找到有这样问题。只能一点点调试,找问题出在哪里。最后终于窥见了一些端倪,总结如下:

 

一,出现的问题的详细描述

1.首先我设置的调度策略是withMisfireHandlingInstructionDoNothing,意思是不触发立即执行,并且错过触发时间的话等待下次Cron触发频率到达时刻开始按照Cron频率依次执行。

2.启动调度系统后,我多次把任务添加进调度系统,有些能正确执行,有些则不会执行第一次触发,当时我的cron是0 * * * * ? *(在每分钟的0秒触发),开始时间设置得很靠前,结束时间设置在几天之后。我发现总有那么一个时间分界线,在这个分界线之前添加进quartz的任务正常,在这个分界线之后添加进quartz的任务就会出问题,每次重启调度系统之后这个分界线就会有变动。有时是20多秒,有时40多秒,不固定。

3.如果我把开始时间设置在我把任务添加进quartz的时间之后,就不会出现问题。(比如说我是在11:56:02把任务添加进调度系统的,如果开始时间是11:42:02就会有问题,如果是11:57:02就正常)

4.如果不做持久化,而是把数据都放到内存里,不会出现任何上述问题

 

二、产生bug的原因

1.quartz在接收到添加新任务的请求后会计算在开始时间之后的第一次触发的时间,然后把这个时间当成下一次触发的时间,但是当我在11:56:02把开始时间是11:42:02的任务添加进来的时候,它计算到11:43:00是下一次触发的时间,实际上应该是11:57:00。所以到11:57:00的时候它不会执行,他还在等11:43:00到来。

2.按照第一条来说,那这个任务应该永远都不会触发了才对,但实际上quartz每分钟都会把QRTZ_TRIGGERS这张表的内容扫描一次,把该更新的东西更新,这时候它发现下一次执行时间11:43:00比当前时间11:57:30还要靠前的时候,就会改正这个字段的值设置为11:58:00。这就是为什么错过了第一次触发,而没有错过第二次触发。至于为什么quartz是每分钟扫描一次而不是每十分钟,每小时,我也不清楚。只是知道第一次扫描的时间是启动调度系统的时间。

3.因此,只有当开始时间在任务添加进quartz的时间之前,且第一次触发的时间在任务添加进quartz的时间之后的一分钟之内才有可能出现这种第一次不触发的问题。

 

 

 

最后

以上就是傲娇悟空为你收集整理的quartz在用mysql做持久化有时候会错过调度的问题的全部内容,希望文章能够帮你解决quartz在用mysql做持久化有时候会错过调度的问题所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(76)

评论列表共有 0 条评论

立即
投稿
返回
顶部