Camunda / Activit (Boundary) Timer 事件值 < 10 秒

Camunda / Activit (Boundary) Timer Event value < 10 seconds

我有一个流程如下图。我想每 X 秒执行一些任务。当我将 CRON(0/5 * * * * ? 应该是每 5 秒)时间或 ISO 时间(R3/PT5S - 每 5 秒执行 3 次)< 边界计时器事件的循环时间中的 10 秒时,它被执行每秒左右(不是指定的值)。如果我使用 0/10 * * * * ? 一切正常,事件每 10 秒执行一次。

我的最终目标是每 X 秒持续执行一次计算,而流程的 "rest",即原始业务流程,按照 BPMN 模型的描述执行。

Process Example

XML 进程文件:

<?xml version="1.0" encoding="UTF-8"?>
<bpmn2:definitions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:bpmn2="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:camunda="http://activiti.org/bpmn" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" xmlns:fox="http://www.camunda.com/fox" xsi:schemaLocation="http://www.omg.org/spec/BPMN/20100524/MODEL BPMN20.xsd" id="_cus4wJ7cEeWDYppcvQHBrQ" exporter="camunda modeler" exporterVersion="2.7.0" targetNamespace="http://activiti.org/bpmn">
  <bpmn2:process id="timerTest" name="Timer Test" isExecutable="true">
    <bpmn2:receiveTask id="waitingForMessage" camunda:async="true" camunda:exclusive="false" name="Waiting For Message" messageRef="Message_2">
      <bpmn2:incoming>SequenceFlow_22</bpmn2:incoming>
      <bpmn2:outgoing>SequenceFlow_17</bpmn2:outgoing>
    </bpmn2:receiveTask>
    <bpmn2:sequenceFlow id="SequenceFlow_17" name="" sourceRef="waitingForMessage" targetRef="end"/>
    <bpmn2:endEvent id="endCheckingTime" name="End Checking Time">
      <bpmn2:incoming>SequenceFlow_26</bpmn2:incoming>
    </bpmn2:endEvent>
    <bpmn2:task id="checkRemainingTime" name="Check Remaining Time">
      <bpmn2:extensionElements>
        <camunda:executionListener class="timerTest.ExecutionListenerCheckRemainingTime" event="start"/>
      </bpmn2:extensionElements>
      <bpmn2:incoming>SequenceFlow_4</bpmn2:incoming>
      <bpmn2:outgoing>SequenceFlow_26</bpmn2:outgoing>
    </bpmn2:task>
    <bpmn2:sequenceFlow id="SequenceFlow_26" name="" sourceRef="checkRemainingTime" targetRef="endCheckingTime"/>
    <bpmn2:boundaryEvent id="BoundaryEvent_3" name="" attachedToRef="waitingForMessage" cancelActivity="false">
      <bpmn2:outgoing>SequenceFlow_18</bpmn2:outgoing>
      <bpmn2:timerEventDefinition id="_TimerEventDefinition_12">
        <bpmn2:timeCycle xsi:type="bpmn2:tFormalExpression">0/5 * * * * ?</bpmn2:timeCycle>
      </bpmn2:timerEventDefinition>
    </bpmn2:boundaryEvent>
    <bpmn2:sequenceFlow id="SequenceFlow_18" name="" sourceRef="BoundaryEvent_3" targetRef="ExclusiveGateway_1"/>
    <bpmn2:endEvent id="end" name="End Waiting">
      <bpmn2:incoming>SequenceFlow_17</bpmn2:incoming>
    </bpmn2:endEvent>
    <bpmn2:exclusiveGateway id="ExclusiveGateway_1" default="SequenceFlow_5">
      <bpmn2:incoming>SequenceFlow_18</bpmn2:incoming>
      <bpmn2:outgoing>SequenceFlow_4</bpmn2:outgoing>
      <bpmn2:outgoing>SequenceFlow_5</bpmn2:outgoing>
    </bpmn2:exclusiveGateway>
    <bpmn2:sequenceFlow id="SequenceFlow_4" name="" sourceRef="ExclusiveGateway_1" targetRef="checkRemainingTime">
      <bpmn2:conditionExpression xsi:type="bpmn2:tFormalExpression"><![CDATA[${counter<5}]]></bpmn2:conditionExpression>
    </bpmn2:sequenceFlow>
    <bpmn2:endEvent id="EndEvent_1">
      <bpmn2:incoming>SequenceFlow_5</bpmn2:incoming>
    </bpmn2:endEvent>
    <bpmn2:sequenceFlow id="SequenceFlow_5" name="" sourceRef="ExclusiveGateway_1" targetRef="EndEvent_1">
      <bpmn2:extensionElements>
        <camunda:executionListener class="timerTest.ExecutionListenerSendEndMessage" event="take"/>
      </bpmn2:extensionElements>
    </bpmn2:sequenceFlow>
    <bpmn2:startEvent id="StartEvent_2">
      <bpmn2:outgoing>SequenceFlow_22</bpmn2:outgoing>
    </bpmn2:startEvent>
    <bpmn2:sequenceFlow id="SequenceFlow_22" name="" sourceRef="StartEvent_2" targetRef="waitingForMessage"/>
    <bpmn2:textAnnotation id="TextAnnotation_1">
      <bpmn2:text><![CDATA[Problems with times < 10 Sec - No clue why]]></bpmn2:text>
    </bpmn2:textAnnotation>
    <bpmn2:association id="Association_2" sourceRef="TextAnnotation_1" targetRef="BoundaryEvent_3"/>
  </bpmn2:process>
  <bpmn2:message id="Message_2" name="testMessage"/>
  <bpmndi:BPMNDiagram id="BPMNDiagram_1">
    <bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="timerTest">
      <bpmndi:BPMNShape id="_BPMNShape_EndEvent_7" bpmnElement="endCheckingTime">
        <dc:Bounds height="36.0" width="36.0" x="561.0" y="299.0"/>
        <bpmndi:BPMNLabel>
          <dc:Bounds height="22.0" width="119.0" x="520.0" y="340.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="_BPMNShape_Task_12" bpmnElement="checkRemainingTime">
        <dc:Bounds height="80.0" width="100.0" x="381.0" y="277.0"/>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNEdge id="BPMNEdge_SequenceFlow_26" bpmnElement="SequenceFlow_26" sourceElement="_BPMNShape_Task_12" targetElement="_BPMNShape_EndEvent_7">
        <di:waypoint xsi:type="dc:Point" x="481.0" y="317.0"/>
        <di:waypoint xsi:type="dc:Point" x="561.0" y="317.0"/>
        <bpmndi:BPMNLabel>
          <dc:Bounds height="6.0" width="6.0" x="743.0" y="329.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNShape id="_BPMNShape_StartEvent_3" bpmnElement="StartEvent_2">
        <dc:Bounds height="36.0" width="36.0" x="12.0" y="187.0"/>
        <bpmndi:BPMNLabel>
          <dc:Bounds height="0.0" width="0.0" x="30.0" y="228.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="_BPMNShape_EndEvent_9" bpmnElement="end">
        <dc:Bounds height="36.0" width="36.0" x="561.0" y="187.0"/>
        <bpmndi:BPMNLabel>
          <dc:Bounds height="22.0" width="77.0" x="541.0" y="228.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="_BPMNShape_TextAnnotation_2" bpmnElement="TextAnnotation_1">
        <dc:Bounds height="61.0" width="229.0" x="708.0" y="231.0"/>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="_BPMNShape_ReceiveTask_3" bpmnElement="waitingForMessage">
        <dc:Bounds height="80.0" width="100.0" x="168.0" y="165.0"/>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNEdge id="BPMNEdge_SequenceFlow_17" bpmnElement="SequenceFlow_17" sourceElement="_BPMNShape_ReceiveTask_3" targetElement="_BPMNShape_EndEvent_9">
        <di:waypoint xsi:type="dc:Point" x="268.0" y="205.0"/>
        <di:waypoint xsi:type="dc:Point" x="561.0" y="205.0"/>
        <bpmndi:BPMNLabel>
          <dc:Bounds height="6.0" width="6.0" x="163.0" y="212.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNShape id="_BPMNShape_BoundaryEvent_8" bpmnElement="BoundaryEvent_3">
        <dc:Bounds height="36.0" width="36.0" x="227.0" y="227.0"/>
        <bpmndi:BPMNLabel>
          <dc:Bounds height="6.0" width="6.0" x="242.0" y="268.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNEdge id="BPMNEdge_SequenceFlow_18" bpmnElement="SequenceFlow_18" sourceElement="_BPMNShape_BoundaryEvent_8" targetElement="_BPMNShape_ExclusiveGateway_2">
        <di:waypoint xsi:type="dc:Point" x="245.0" y="263.0"/>
        <di:waypoint xsi:type="dc:Point" x="245.0" y="284.0"/>
        <di:waypoint xsi:type="dc:Point" x="271.0" y="284.0"/>
        <di:waypoint xsi:type="dc:Point" x="271.0" y="306.0"/>
        <bpmndi:BPMNLabel>
          <dc:Bounds height="6.0" width="6.0" x="150.0" y="298.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNShape id="_BPMNShape_ExclusiveGateway_2" bpmnElement="ExclusiveGateway_1" isMarkerVisible="true">
        <dc:Bounds height="50.0" width="50.0" x="246.0" y="306.0"/>
        <bpmndi:BPMNLabel>
          <dc:Bounds height="0.0" width="0.0" x="271.0" y="361.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNEdge id="BPMNEdge_SequenceFlow_4" bpmnElement="SequenceFlow_4" sourceElement="_BPMNShape_ExclusiveGateway_2" targetElement="_BPMNShape_Task_12">
        <di:waypoint xsi:type="dc:Point" x="296.0" y="331.0"/>
        <di:waypoint xsi:type="dc:Point" x="338.0" y="331.0"/>
        <di:waypoint xsi:type="dc:Point" x="338.0" y="317.0"/>
        <di:waypoint xsi:type="dc:Point" x="381.0" y="317.0"/>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNShape id="_BPMNShape_EndEvent_11" bpmnElement="EndEvent_1">
        <dc:Bounds height="36.0" width="36.0" x="366.0" y="405.0"/>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNEdge id="BPMNEdge_SequenceFlow_5" bpmnElement="SequenceFlow_5" sourceElement="_BPMNShape_ExclusiveGateway_2" targetElement="_BPMNShape_EndEvent_11">
        <di:waypoint xsi:type="dc:Point" x="271.0" y="356.0"/>
        <di:waypoint xsi:type="dc:Point" x="271.0" y="423.0"/>
        <di:waypoint xsi:type="dc:Point" x="366.0" y="423.0"/>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="BPMNEdge_Association_2" bpmnElement="Association_2" sourceElement="_BPMNShape_TextAnnotation_2" targetElement="_BPMNShape_BoundaryEvent_8">
        <di:waypoint xsi:type="dc:Point" x="708.0" y="258.0"/>
        <di:waypoint xsi:type="dc:Point" x="263.0" y="245.0"/>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="BPMNEdge_SequenceFlow_22" bpmnElement="SequenceFlow_22" sourceElement="_BPMNShape_StartEvent_3" targetElement="_BPMNShape_ReceiveTask_3">
        <di:waypoint xsi:type="dc:Point" x="48.0" y="205.0"/>
        <di:waypoint xsi:type="dc:Point" x="168.0" y="205.0"/>
      </bpmndi:BPMNEdge>
    </bpmndi:BPMNPlane>
  </bpmndi:BPMNDiagram>
</bpmn2:definitions>

如果您使用默认的 jobExecutor(即不是 Activiti 5.17+ 中的 asyncjobExecutor),您的问题的答案非常简单。

如果您查看 JobExecutor 代码,您将看到:

  protected int maxJobsPerAcquisition = 1;
  protected long waitTimeInMillis = 5000L;
  protected String lockOwner = UUID.randomUUID().toString();
  protected int lockTimeInMillis = 5 * 60 * 1000;
  protected ClockReader clockReader;

注意作业获取之间的等待时间默认为 5 秒,因此任何小于 5 秒的计时器都会有 "unpredictable" 个结果。