[15]深入浅出工作开源框架Camunda:定时任务

Posted 朱清云的技术博客

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[15]深入浅出工作开源框架Camunda:定时任务相关的知识,希望对你有一定的参考价值。

1.引言

在BPMN中,可以通过改变“Timer Start Event” 启动节点的启动类型来自动启动流程实例。
其提供了下面三种定时自动触发流程实例的模式:

  • 指定固定的时间点启动一个新的流程实例
  • 指定相对延迟时间启动一个新的流程实例
  • 周期性的启动一个新的流程实例

下面分别就上面的三种方式进行设计和实验~
三种使用方式,如下:
(1)Date:特定时间(例:2022-05-25T16:00:00)
其支持的是ISO 8601标准,需要注意是,如果最后带了“Z”,说明用的是带时区的时间。
比如下面的例子,
2019-10-01T12:00:00Z - UTC time
2019-10-02T08:09:40+02:00 - UTC plus two hours zone offset 相对UTC时区加了2个时区
2019-10-02T08:09:40+02:00[Europe/Berlin] - UTC plus two hours zone offset at Berlin

如果不加Z表示就是当地的时间。 比如这个2022-05-25T16:00:00设置,其意思就是流程部署后,会在应用部署的时区内2022-05-25 16:00的时候启动一次而且仅仅一次~

(2)Duration: 延迟时间(例:PT10M)
Duration的格式符合ISO_8601标准,其格式如下:

  • P(n)Y(n)M(n)DT(n)H(n)M(n)S 其中n代表的具体的数值
  • PnW

其具体说明如下:

  • P is the duration designator (for period) placed at the start of the duration representation. 主要指周期
  • Y is the year designator that follows the value for the number of years. 代表年
  • M is the month designator that follows the value for the number of months. 代表月
  • W is the week designator that follows the value for the number of weeks. 代表周的缩写
  • D is the day designator that follows the value for the number of days. 代表天的缩写
  • T is the time designator that precedes the time components of the representation. 代表前置时间
  • H is the hour designator that follows the value for the number of hours. 代表小时
  • M is the minute designator that follows the value for the number of minutes. 代表分钟
  • S is the second designator that follows the value for the number of seconds. 代表秒

其中P, Y, M, W, D, T, H, M, and S 能被忽略但是不能被替换

比如:PT10M标识其在部署后,10分钟后启动流程~

再来看一些例子:
PT15S - 15 seconds 15秒后创建一个流程实例~
PT1H30M - 1 hour and 30 minutes 1个小时30分钟后创建一个流程实例~
P14D - 14 days 14天后创建流程~
P14DT1H30M - 14 days, 1 hour and 30 minutes 14天1小时30分钟后创建一个流程实例~
P3Y6M4DT12H30M5S - 3 years, 6 months, 4 days, 12 hours, 30 minutes and 5 seconds 3年6个月4天12个小时30分5秒后创建一个流程实例~

(3)Cycle:循环时间(例:RS3/2022-05-25T16:00:00/PT30S)
Cycle支持的标准是ISO_8601的重复间隔标准
下面是具体的例子:
R5/PT10S: Every 10 seconds, up to five times 每10秒触发一次,最多5次
R/P1D: Every day, infinitely ; 每天触发一次,无限循环
当然其也支持Cron的正则表达式,
比如下面就代表其当前的流程实例每隔5分钟就会启动一次:

0 0/5 * * * ?

下面举一个例子,比如下面的2022-05-25T16:00:00,每间隔30s就会触发一次,总共触发3次;

格式解析
RS3/2022-05-25T16:00:00/PT30S
重复次数/开始时间/运行间隔
重复次数:R - 将永远重复;R3- 将重复3次。
开始时间 :2021年11月19日16点00分00秒开始
运行间隔 :30秒

例如: P1Y2M3DT2H10M30S 表示间隔1年2个月3天2小时10分钟30秒
PT2M 表示间隔2分钟(Per Time 2 minutes)
注意:T是时间和日期分的割标记,如果没有年月日"T"也不能省略

  • 计时器启动事件可用特定时间或者循环时间
  • 中间计时器事件可用特定时间或延迟时间。
  • 周期时间用于计时器启动事件或附加的非中断计时器边界事件

2.Camunda的实现原理

通过观察Camunda的数据库的变化,我们可以推测出其实现的原理。下面一个一个的来看:
(1)Date:特定时间(例:2022-05-25T10:40:00)

<?xml version="1.0" encoding="UTF-8"?>
<bpmn:definitions xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:camunda="http://camunda.org/schema/1.0/bpmn" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" xmlns:modeler="http://camunda.org/schema/modeler/1.0" id="Definitions_1mnxduk" targetNamespace="http://bpmn.io/schema/bpmn" exporter="Camunda Modeler" exporterVersion="4.11.1" modeler:executionPlatform="Camunda Platform" modeler:executionPlatformVersion="7.15.0">
  <bpmn:process id="Process_14pjj1v" name="请假流程" isExecutable="true">
    <bpmn:startEvent id="StartEvent_1" name="特定时间启动">
      <bpmn:outgoing>Flow_1ihjej0</bpmn:outgoing>
      <bpmn:timerEventDefinition id="TimerEventDefinition_0bshgz6">
        <bpmn:timeDate xsi:type="bpmn:tFormalExpression">2022-05-24T10:53:00</bpmn:timeDate>
      </bpmn:timerEventDefinition>
    </bpmn:startEvent>
    <bpmn:sequenceFlow id="Flow_1ihjej0" sourceRef="StartEvent_1" targetRef="Activity_1tiqpqb" />
    <bpmn:sequenceFlow id="Flow_0748tlu" sourceRef="Activity_1tiqpqb" targetRef="Activity_0jzwi5i" />
    <bpmn:endEvent id="Event_1yb23ri" name="结束">
      <bpmn:incoming>Flow_0a6rwts</bpmn:incoming>
    </bpmn:endEvent>
    <bpmn:sequenceFlow id="Flow_0a6rwts" sourceRef="Activity_0jzwi5i" targetRef="Event_1yb23ri" />
    <bpmn:userTask id="Activity_1tiqpqb" name="请假" camunda:assignee="demo">
      <bpmn:incoming>Flow_1ihjej0</bpmn:incoming>
      <bpmn:outgoing>Flow_0748tlu</bpmn:outgoing>
    </bpmn:userTask>
    <bpmn:userTask id="Activity_0jzwi5i" name="审批" camunda:assignee="demo">
      <bpmn:incoming>Flow_0748tlu</bpmn:incoming>
      <bpmn:outgoing>Flow_0a6rwts</bpmn:outgoing>
    </bpmn:userTask>
  </bpmn:process>
  <bpmndi:BPMNDiagram id="BPMNDiagram_1">
    <bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Process_14pjj1v">
      <bpmndi:BPMNEdge id="Flow_1ihjej0_di" bpmnElement="Flow_1ihjej0">
        <di:waypoint x="215" y="117" />
        <di:waypoint x="270" y="117" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="Flow_0748tlu_di" bpmnElement="Flow_0748tlu">
        <di:waypoint x="370" y="117" />
        <di:waypoint x="430" y="117" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="Flow_0a6rwts_di" bpmnElement="Flow_0a6rwts">
        <di:waypoint x="530" y="117" />
        <di:waypoint x="592" y="117" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNShape id="Event_1xfvi9y_di" bpmnElement="StartEvent_1">
        <dc:Bounds x="179" y="99" width="36" height="36" />
        <bpmndi:BPMNLabel>
          <dc:Bounds x="165" y="142" width="65" height="14" />
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="Event_1yb23ri_di" bpmnElement="Event_1yb23ri">
        <dc:Bounds x="592" y="99" width="36" height="36" />
        <bpmndi:BPMNLabel>
          <dc:Bounds x="599" y="142" width="22" height="14" />
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="Activity_0sq8nj2_di" bpmnElement="Activity_1tiqpqb">
        <dc:Bounds x="270" y="77" width="100" height="80" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="Activity_0pt371x_di" bpmnElement="Activity_0jzwi5i">
        <dc:Bounds x="430" y="77" width="100" height="80" />
      </bpmndi:BPMNShape>
    </bpmndi:BPMNPlane>
  </bpmndi:BPMNDiagram>
</bpmn:definitions>


部署之后,查询 select * from ACT_RU_JOB,其里面添加了一条新的数据;

 select * from ACT_RU_JOB

"select * from ACT_RU_JOB": [
	
		"ID_" : "225e7949-db0c-11ec-8676-005056c00008",
		"REV_" : 1,
		"TYPE_" : "timer",
		"LOCK_EXP_TIME_" : null,
		"LOCK_OWNER_" : null,
		"EXCLUSIVE_" : 1,
		"EXECUTION_ID_" : null,
		"PROCESS_INSTANCE_ID_" : null,
		"PROCESS_DEF_ID_" : "Process_14pjj1v:1:225d19b7-db0c-11ec-8676-005056c00008",
		"PROCESS_DEF_KEY_" : "Process_14pjj1v",
		"RETRIES_" : 3,
		"EXCEPTION_STACK_ID_" : null,
		"EXCEPTION_MSG_" : null,
		"FAILED_ACT_ID_" : null,
		"DUEDATE_" : "2022-05-24 10:53:00",
		"REPEAT_" : null,
		"REPEAT_OFFSET_" : 0,
		"HANDLER_TYPE_" : "timer-start-event",
		"HANDLER_CFG_" : "Process_14pjj1v",
		"DEPLOYMENT_ID_" : "22577465-db0c-11ec-8676-005056c00008",
		"SUSPENSION_STATE_" : 1,
		"JOB_DEF_ID_" : "225d19b8-db0c-11ec-8676-005056c00008",
		"PRIORITY_" : 0,
		"SEQUENCE_COUNTER_" : 1,
		"TENANT_ID_" : null,
		"CREATE_TIME_" : "2022-05-24 10:49:30"
	
]


Job的定义如下:


"select * from ACT_RU_JOBDEF": [
	
		"ID_" : "225d19b8-db0c-11ec-8676-005056c00008",
		"REV_" : 1,
		"PROC_DEF_ID_" : "Process_14pjj1v:1:225d19b7-db0c-11ec-8676-005056c00008",
		"PROC_DEF_KEY_" : "Process_14pjj1v",
		"ACT_ID_" : "StartEvent_1",
		"JOB_TYPE_" : "timer-start-event",
		"JOB_CONFIGURATION_" : "DATE: 2022-05-24T10:53:00",
		"SUSPENSION_STATE_" : 1,
		"JOB_PRIORITY_" : null,
		"TENANT_ID_" : null,
		"DEPLOYMENT_ID_" : null
	
]


同时执行查询 select * from ACT_RU_TASK, 其表是空的

这个时候,我们看到用户任务里面没有待审批的工作流,表ACT_RU_TASK和ACT_RU_EXECUTION
也查询不到数据。

等到2022-05-24T10:53的时候,我们可以看到任务出现在Demo用户下:

同时,表ACT_RU_JOB里面的响应记录被删除;表ACT_RU_TASK和ACT_RU_EXECUTION有执行记录。


"select * from ACT_RU_TASK": [
	
		"ID_" : "ad612c9e-db0c-11ec-8676-005056c00008",
		"REV_" : 1,
		"EXECUTION_ID_" : "ad60de7b-db0c-11ec-8676-005056c00008",
		"PROC_INST_ID_" : "ad60de7b-db0c-11ec-8676-005056c00008",
		"PROC_DEF_ID_" : "Process_14pjj1v:1:225d19b7-db0c-11ec-8676-005056c00008",
		"CASE_EXECUTION_ID_" : null,
		"CASE_INST_ID_" : null,
		"CASE_DEF_ID_" : null,
		"NAME_" : "请假",
		"PARENT_TASK_ID_" : null,
		"DESCRIPTION_" : null,
		"TASK_DEF_KEY_" : "Activity_1tiqpqb",
		"OWNER_" : null,
		"ASSIGNEE_" : "demo",
		"DELEGATION_" : null,
		"PRIORITY_" : 50,
		"CREATE_TIME_" : "2022-05-24 10:53:24",
		"DUE_DATE_" : null,
		"FOLLOW_UP_DATE_" : null,
		"SUSPENSION_STATE_" : 1,
		"TENANT_ID_" : null
	
]


"select * from ACT_RU_EXECUTION": [
	
		"ID_" : "ad60de7b-db0c-11ec-8676-005056c00008",
		"REV_" : 1,
		"ROOT_PROC_INST_ID_" : "ad60de7b-db0c-11ec-8676-005056c00008",
		"PROC_INST_ID_" : "ad60de7b-db0c-11ec-8676-005056c00008",
		"BUSINESS_KEY_" : null,
		"PARENT_ID_" : null,
		"PROC_DEF_ID_" : "Process_14pjj1v:1:225d19b7-db0c-11ec-8676-005056c00008",
		"SUPER_EXEC_" : null,
		"SUPER_CASE_EXEC_" : null,
		"CASE_INST_ID_" : null,
		"ACT_ID_" : "Activity_1tiqpqb",
		"ACT_INST_ID_" : "Activity_1tiqpqb:ad61058d-db0c-11ec-8676-005056c00008",
		"IS_ACTIVE_" : 1,
		"IS_CONCURRENT_" : 0,
		"IS_SCOPE_" : 1,
		"IS_EVENT_SCOPE_" : 0,
		"SUSPENSION_STATE_" : 1,
		"CACHED_ENT_STATE_" : 2,
		"SEQUENCE_COUNTER_" : 3,
		"TENANT_ID_" : null
	
]

(2)Duration: 延迟时间(例:PT3M,PT60S)
下面让当前的任务在部署后延迟3分钟后启动,流程如下:

<?xml version="1.0" encoding="UTF-8"?>
<bpmn:definitions xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:camunda="http://camunda.org/schema/1.0/bpmn" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" xmlns:modeler="http://camunda.org/schema/modeler/1.0" id="Definitions_07guhgc" targetNamespace="http://bpmn.io/schema/bpmn" exporter="Camunda Modeler" exporterVersion="4.11.1" modeler:executionPlatform="Camunda Platform" modeler:executionPlatformVersion="7.15.0">
  <bpmn:process id="Process_1l8shll" name="定时启动流程" isExecutable="true">
    <bpmn:startEvent id="StartEvent_1"以上是关于[15]深入浅出工作开源框架Camunda:定时任务的主要内容,如果未能解决你的问题,请参考以下文章

[5]深入浅出工作开源框架Camunda: 解读 camunda-webapp 笔记

[7]深入浅出工作开源框架Camunda: camunda-webapp 用户登录功能代码分析

[7]深入浅出工作开源框架Camunda: camunda-webapp 用户登录功能代码分析

[3] 深入浅出工作开源框架Camunda: Camunda 切换到MySQL数据库

[1]深入浅出工作开源框架Camunda: 安装和使用

[6]深入浅出工作开源框架Camunda: 如何远程Debug camunda-webapp的源代码