对应的五张表
基于flowable6.5版本,都以_JOB结尾,表之间的数据可以通过API接口进行流通
- 定时作业表(
ACT_RU_TIMER_JOB
) - 定时作业执行表(
ACT_RU_JOB
) - 死信作业表(
ACT_RU_DEADLETTER_JOB
) - 挂起作业表(
ACT_RU_SUSPENDED_JOB
) - 异步历史作业表(
ACT_RU_HISTORY_JOB
)
开启异步任务
默认开启状态
flowable:
# 异步执行器
asyncExecutorActivate: true
# 异步历史执行器
asyncHistoryExecutorActivate: true
配置异步历史
<property name="asyncHistoryEnabled" value="true" />
<property name="asyncHistoryExecutorNumberOfRetries" value="10" />
asyncHistoryExecutorNumberOfRetries
参数用于配置异步历史作业的重试次数
异步节点
开启流程异步节点
配置 async
属性为开启
<userTask id="usertask3" name="3" activiti:async="true" activiti:candidateUsers="{小爱,肖锋}"></userTask>
异步执行器的设计
Flowable有两种作业类型:定时器(例如边界事件或用户任务中的定时器)以及异步操作(带有_flowable:async="true"_属性的服务任务)。
定时器很容易理解:保存在ACT_RU_TIMER_JOB
表中,并带有给定的到期日期。异步执行器中有一个线程,周期性地检查是否有需要触发的定时器(也就是说,到期日期在当前时间“之前”)。当需要触发定时器时,从JOB表中移除该定时器,并创建一个异步作业(async job)。
异步作业在执行流程实例(即调用API)时插入数据库。如果当前Flowable引擎启用了异步执行器,则该异步作业将被_锁定(locked)_。即在ACT_RU_JOB
表中插入一个作业条目,并设置其_lock owner(锁持有人)与_lock expiration time(锁到期时间)。在API调用成功后触发的事务监听器(transaction commit listener),将会触发同一引擎中的异步执行器,让其执行该作业(因此可以保证数据库中已经保存了数据)。为此,异步执行器使用(可配置的)线程池,从其中取出线程用于执行作业,并使流程可以异步进行。如果Flowable引擎未启用异步执行器,则异步作业仍会插入ACT_RU_JOB
表,但不会被锁定。
与检查定时器的线程类似,异步执行器中也有一个用于“获取”新的异步作业的线程。这里的异步作业,指的是表中存储但未被锁定的作业。这个线程会将这些作业锁定给当前Flowable引擎,并发送至异步执行器。
用于执行作业的线程池从一个内存队列中获取作业。当队列满了时(可配置),作业将会被解锁,并重新存回数据库。这样,其他的异步执行器就可以重新操作它们。
如果在执行作业期间发生了异常,这个异步作业将会转化为一个定时器作业,并带有一个到期日期。之后,它将会像普通定时器作业一样被获取,并重新变回异步作业,以实现重试。当一个作业已经重试了(可配置)几次,仍然失败,则作业被视为“死亡(dead)”,并被移至ACT_RU_DEADLETTER_JOB
表。“死信(deadletter)”的概念在各种其他系统中也广泛使用。管理员需要检查失败作业的异常信息,并进行相应操作。
流程定义与流程实例都可以被暂停。这些定义或实例所关联的暂停作业,将被移至ACT_RU_SUSPENDED_JOB
表,以确保用于获取作业的查询语句中的where条件尽量少。
综上所述:对于熟悉作业/异步执行器的旧实现的人来说,主要目标是让查询尽可能简单。在过去(V6以前),所有作业类型/状态使用一张表。为了满足所有使用场景,导致“where”条件十分庞大。现在已经解决了这个问题,我们的跑分也证明这个新设计带来了更好的性能,也更有弹性。[异步执行器的设计][1] [1]: http://www.shareniu.com/flowable6.5_zh_document/bpm/index.html#asyncHistoryConfig
来源:oschina
链接:https://my.oschina.net/u/2555967/blog/3174087