昨天在用taskctl的定时器遇到些问题,暂停了定时器,去修改了定时器调用的作业,再取消暂停的时候,发现取消暂停的时候,该作业重复调用了很多次。后来在群中群主的详细解答下,终于弄了个半懂,在这里也分享给大家。
Taskctl的控制容器分为两种,一种是流程(子流程),一种是定时器。TASKCTL各种控制容器的区别(http://www.taskctl.com/forum/detail_84.html)。其中有关定时器的资料较流程定时器而言少很多。定时器内部是无序的任务集,适合处理定频触发的任务;不像流程那样是一个有序的任务集合,适合处理周期性的任务流。
只所以选择调度工具,而不用系统的crontab之类的东西,其实有一部分原因是因为crontab是不支持自动判断上一次是否执行完了,而是到点执行再次执行,有可能上一次的运行还没有结束,这个时候我们通常的需求都不是这样的。
Taskctl的定时器有三个属性,在范例中说的很清楚,我这里就直接摘抄一下
<!--
定时器名称: Demo_1_Initial_Timer1(范例四:定时调度业务流程方法二)
范例说明:
1. 通过本范例,学习怎么用一个定时器调度一个具体业务子流程
2. 技术层面,相对流程,您必须知道定时器的一个特殊重要属性timingplan属性。
a. timingplan表示任务自动执行的频度周期。周期间隔最小为1秒。timingplan
不设置,表示该任务不自动执行.
b. 通过一下范例认识timingplan的规则
.每5分钟启动: <timingplan>* m 5</timingplan>
.每5秒启动:<timingplan>* s 5</timingplan>
.每5小时启动:<timingplan>* h 5</timingplan>
.每天10点1分1秒启动:<timingplan>100101 d1</timingplan>
-->
这里要弄清楚第二个和第三个参数合起来表达了频率,但是第一个参数不是起始时间,而是基准时间。Taskctl的更加当前时间和基准时间的差值是否是间隔频率的整数倍来决定是不是该执行的,如果第一个参数设置的是*,那默认的是启动定时器是,第一次执行定时任务的时间为基准时间。举例<timingplan>100101 h 1</timingplan> 这个和范例中最后一个的区别是间隔为1小时,因为第一个参数不是起始时间,只是基准时间,所以090101的时候,该任务同样会执行,而不是从每天10点1分1秒开始,每隔一小时运行一次;而<timingplan>100101 d 1</timingplan>,是每天10点1分1秒启动是因为间隔是天,这个地方一定要认真的理解。
当执行作业时长超过频率间隔时,后面的调度会排队,等前一次执行完了,在马上执行新的批次。假如一个作业开始执行1分钟,间隔是5分钟,之前一直正常,当某一个批次跑了21分钟时,这个时候这个作业在栈中还有三次需要被调用,现在恢复了只用执行1分钟时,会依次调用四次。
情况二,也就是我遇到的情况,假如我我有一个作业间隔是10分钟运行一次,每一次运行几秒,最近一次正常的运行的10点钟,现在因为作业要修改下,我暂停了定时器,在11点钟的时候,作业修改好了,我此时取消暂停,这个时候该定时作业会运行6次(每10分钟一次的调用都在栈中)。有时候可能是需要这种逻辑的,但是我此时是不需要这么做。那这种情况就应该是停止定时器而不是暂停定时器。停止定时器,会把当前定时器中所有还没有做完的在栈中存着调度计划都清楚掉。