执行计划介绍原创
金蝶云社区-eris
eris
16人赞赏了该文章 8,829次浏览 未经作者许可,禁止转载编辑于2021年08月18日 15:18:58
summary-icon摘要由AI智能服务提供

文本介绍了执行计划的四个主要过程:从数据库取数据、调度执行计划、运行执行计划(含插件运行)及处理返回结果。执行过程由Job类管理三个定时器实现,确保计划按时执行。服务插件在特定条件下执行,并更新执行结果和计划状态。文本还讨论了执行计划的状态管理、执行时间计算、异常处理及常见问题解答,包括停止状态的影响、长时间服务插件的执行情况、下次执行时间计算等。

一、执行计划主要分四个过程:

  1. 去数据库取执行计划数据(定时器每隔10分钟取一次)

  2. 调度执行计划去运行(定时器每隔1秒钟循环队列中所有执行计划)

  3. 运行执行计划(使用一个任务去运行插件运行)

  4. 处理插件返回结果(更新执行计划相关情况到数据库)

备注:1,2,3是并行执行的,3和4是顺序执行

二、大概过程:

启动Windows后台服务(K3CloudJobProcess),后台服务创建Job类,Job类使用一个定时器去数据库取出满足条件的执行计划,Job类使用另外一个定时器把执行计划封送给通道类,通道类为每个执行计划开一个后台任务,后台任务为满足条件的执行计划创建插件类实例并允许插件。执行计划的执行:狭义为服务插件的执行,广义包括从数据库取,调度,任务运行,服务插件运行等系列过程。

Job类(主要管理三个定时器):
1. 取执行计划定时器,每隔10分钟执行一次,主要功能是去数据库取满足条件的(为准备状态或启用异常恢复为运行状态)执行计划,并把取到的执行计划覆盖执行计划队列。
2. 调度定时器,每隔1秒钟执行一次,去队列调度所有执行计划去运行,被调度的执行计划会从队列中移除并计算下次的执行时间,计算完下一次执行时间就又放回到队列中。被调度的执行计划能否封送给运行类需要满足执行时间小于当前时间,开始时间小于当前时间,结束时间大于当前时间。
3. 异常恢复定时器,每隔24小时运行一次,运行和停止状态下的执行计划并且勾选了异常自动恢复会被自动恢复。
运行类:
1. 在运行之前会做验证,执行类是否有效,执行计划是否正在执行,执行计划是否在准备状态等。只有准备状态,非运行中,执行类有效的执行计划才会真正去执行。这里的运行中的检查包括在内存中,数据库中的检查。如果可以运行则会把数据库中的状态更新为运行状态。
2. 执行完就会去更新内存和数据库中下一次的执行时间和把执行计划的状态恢复为准备状态和执行情况说明。
调度类和运行类中的下一次执行时间说明:
1. 下一次执行时间 (T1)= 当前次执行时间 + 执行计划的时间间隔(p0)
2. 下一次执行时间如果小于当前时间,则会去取它们的时间间隔,然后除以执行计划的时间间隔,并向下取整,最后把取到的整数乘以执行计划的时间间隔得到的时间 被加到下一次执行时间上,从而得到下一次执行时间。
从而可以发现如果执行的时间超过设置的时间间隔,就需要去做矫正,矫正到离当前时间最近的那个时间间隔内,矫正后的时间永远小于当前时间。
最后说明:
为什么每隔10分钟去数据库中取执行计划啊,这是因为金蝶云星空要保证高可用性,往往会部署多个应用服务器,每个服务器都有后台服务,但在每个时间间隔内只有一台服务可以取到。

执行计划未执行问题排查: https://vip.kingdee.com/article/42750

创建执行计划:https://vip.kingdee.com/article/35401

另外角度介绍:

一。执行计划分四个阶段:

1. 数据库取出阶段:
1.1 时间:10分钟取一次。
1.2 条件:执行时间,开始时间和结束时间不为空并且(状态为准备或为运行(最新版本支持))。
1.3 结果:把取到的执行计划覆盖调度队列。

2. 调度阶段:
2.1 时间:每一秒。
2.2 功能:把调度队列中的所有执行计划调度去运行。
2.3 运行条件:开始时间小于当前时间 并且 结束时间大于当前时间 并且执行时间小于当前时间(跟状态没有关系)
2.4 结果:满足条件的执行计划被封送去执行,并且更新执行计划下一次的执行时间。

3.任务执行阶段(服务插件的执行包含在此阶段中):
3.1 条件:状态非停止 并且 非运行中 ;这里的非运行是一个判断包括内存和数据库中的判断。
3.2 如果不满足条件:则会更新执行说明,并产生不成功的执行结果。
3.3 满足条件:执行服务插件,服务插件执行完返回到平台,平台则会更新执行说明和下一次执行时间,并产生成功的执行结果。

4. 服务插件执行阶段:
1. 正常返回结果:更新最近一次执行情况,执行时间,并把执行计划状态恢复为准备状态。
2. 异常返回:更新最近一次执行情况,执行计划状态(更新为执行计划当前持有的状态,服务插件为设置,则为运行中状态)。

现在问题:
1. 如果手动把执行计划设置为停止状态会产生什么影响?
答:数据库取阶段:再也取不出来。
调度阶段:调度队列中的数据未被覆盖之前依然被调度。
任务执行阶段:未执行的服务插件不会执行,并且会更新最近一次执行情况。
服务插件执行阶段:继续运行,确运行完的结果无法更新到数据库。

2. 执行计划为准备状态,间隔2分钟,服务插件每次运行6分钟才能完成,其他条件也满足,它的执行情况是怎样?
答:每隔10分钟被取出来,每隔一秒钟会被调度一次,
每隔两分钟会被调度到任务运行阶段(可以看到结果),
每三次在运行阶段会有一次服务插件执行,也既三次运行结果有两次失败一次成功。

3.服务插件执行完,下一次执行时间怎么算?
3.1 如果当前次执行时间+时间间隔 > 当前时间,则下一次执行时间 = 当前次执行时间+时间间隔
3.2 如果当前次执行时间+时间间隔 < 当前时间, 则下一次执行时间 = ((分)(当前时间-当前次执行时间)/ (分)时间间隔)*(分)时间间隔 +当前次执行时间
  示例(假设时间间隔为3分钟,当前次执行时间:10:00,当前时间为:10:10):
  则下一次执行时间 =((10:10-10:00)/3)*3+10:00=(10/3)*3+10:00=3*3+10:00=10:09

4. 执行计划中的服务插件到底会不会执行?
答:整个后台服务再运行(可以看有没有其他执行计划在运行),满足条件(准备状态,时间)一定会执行的 。