Flowable 是 Activiti 的一个强劲分支,由 Activiti 的核心团队创建,在保留 Activiti 优点的同时,对性能和灵活性做了深度优化,并保持活跃的迭代更新。
🚀 核心架构:Flowable的工作原理
Flowable的设计思想是让流程引擎(Process Engine)作为大脑,来解析和执行 BPMN 文件定义的流程蓝图。
核心组件与数据存储
- ProcessEngine(流程引擎):总控制器,所有流程操作都通过它提供的API发起。它是线程安全的,通常在应用启动时创建一次。
- Services(服务接口):引擎对外暴露的7大核心API,用于部署、启动、查询、完成任务等。
- BPMN 2.0:流程定义的行业标准,Flowable 引擎能解析和"读懂"用这种标准XML格式绘制的流程图。
- ACT_* 表:运行时和历史的全部状态、变量、任务等数据,都通过MyBatis映射到其强大的ACT_* 系列数据库表中。
数据表梳理:Flowable 启动时会自动生成五类核心表,通过表名前缀即可区分:
- ACT_RE_*:Repository,存储静态的流程定义和模型资源。
- ACT_RU_*:Runtime,存储运行中的流程实例、任务、变量,引擎结束后会清理。
- ACT_HI_*:History,存储已完结的流程历史记录。
- ACT_ID_*:Identity,存储用户、用户组信息。
- ACT_GE_*:General,存储通用数据,如二进制文件。
执行原理:从蓝图到现实
整个执行过程像流水线一样,清晰明了:
- 部署 (Deploy) :通过 API 将
.bpmn20.xml流程文件部署到引擎,存入ACT_RE_*表,生成一个流程定义。 - 实例化 (Instantiate) :根据流程定义,创建一个或多个流程实例,并在
ACT_RU_*表记录其运行状态。 - 流转 (Execute):引擎驱动实例执行,根据流程定义生成用户任务或自动调用服务。
- 交互 (Interact):用户通过 API 查询并完成任务(审批/驳回)。引擎负责路由,决定下一步执行什么。
- 结束 (End) :流程到达终点节点,实例结束。运行时数据被清理,历史数据归档到
ACT_HI_*表。
📥 Spring Boot 快速接入指南
接入 Flowable 最标准、最高效的方式是使用官方提供的 flowable-spring-boot-starter。
1. 添加依赖
在 pom.xml 中加入核心依赖:
xml
<dependency>
<groupId>org.flowable</groupId>
<artifactId>flowable-spring-boot-starter</artifactId>
<version>7.1.0</version> <!-- 请使用最新稳定版本 -->
</dependency>
版本选择 :Flowable 7.0 是一个重要里程碑,它要求 JDK 17 和 Spring Boot 3.x,同时引入了更强的云原生支持和对 BPMN、CMMN、DMN 三大规范的完整实现。如果项目仍使用旧版,需选择 6.x 系列。
2. 配置数据源和引擎
在 application.yml 中进行基础配置:
yaml
spring:
datasource:
url: jdbc:mysql://localhost:3306/flowable?useSSL=false&characterEncoding=UTF-8
username: root
password: your_password
driver-class-name: com.mysql.cj.jdbc.Driver
flowable:
database-schema-update: true # 生产环境建议改为 false 或 validate
async-executor-activate: true # 开启异步执行器,处理定时任务和异步操作
database-schema-update: true会让 Flowable 在启动时自动检查并更新表结构,是开发阶段的利器,但在生产环境中极不安全,务必修改。
3. 编写流程定义 (BPMN 2.0)
使用 IDEA 的 Flowable插件 或 Flowable-UI 等工具,按 BPMN 2.0 规范绘制流程图,将生成的 .bpmn20.xml 文件放在 src/main/resources/processes/ 目录下,Spring Boot 启动时会自动扫描并部署。
🛠️ 核心API详解与实战
Flowable 提供了7大核心 Service API,几乎所有的流程操作都通过它们完成。使用时,只需在 Spring Bean 中注入所需 Service 即可。
7大核心服务
| Service 接口 | 核心职责 | 常用方法 |
|---|---|---|
RepositoryService |
管理流程定义(蓝图)的部署、查询、暂停、激活。 | createDeployment().addClasspathResource(...).deploy() createProcessDefinitionQuery().list() |
RuntimeService |
管理流程实例(具体的执行过程)。 | startProcessInstanceByKey(processDefinitionKey, variables) deleteProcessInstance(processInstanceId, deleteReason) |
TaskService |
管理用户任务(待办、完成、签收、委派)。 | createTaskQuery().taskAssignee(userId).list() complete(taskId, variables) |
HistoryService |
查询历史数据(已完成的流程、任务、活动)。 | createHistoricProcessInstanceQuery().finished().list() |
IdentityService |
管理用户和组。 | newUser(userId) |
FormService |
管理与流程关联的表单数据。 | getStartFormKey(processDefinitionId) |
ManagementService |
执行引擎管理和维护操作,如查询数据库表、执行作业。 | executeJob(jobId) |
代码示例:部署与启动流程
java
@Service
public class MyWorkflowService {
@Autowired
private RepositoryService repositoryService;
@Autowired
private RuntimeService runtimeService;
@Autowired
private TaskService taskService;
// 1. 部署流程
public void deployProcess() {
repositoryService.createDeployment()
.addClasspathResource("processes/my_approval_process.bpmn20.xml")
.name("我的审批流程")
.deploy();
}
// 2. 启动流程实例
public ProcessInstance startProcess(String businessKey, Map<String, Object> variables) {
return runtimeService.startProcessInstanceByKey("myApprovalProcess", businessKey, variables);
}
// 3. 查询并完成用户任务
public void completeTask(String taskId, Map<String, Object> variables) {
Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
if (task != null) {
taskService.complete(task.getId(), variables);
}
}
}
⚙️ 配置详解与最佳实践
除了基础的数据源配置,Flowable 提供了丰富的引擎级配置项,以下是几个关键参数:
配置项 (flowable.) |
说明与推荐值 |
|---|---|
database-schema-update |
开发 : true (自动建表/更新) | 生产 : false 或 validate (禁止自动改表) |
async-executor-activate |
必须开启 (true)。用于处理定时器、异步服务任务等,否则流程会在这些节点卡住。 |
history-level |
full (记录完整信息,便于查询,开销最大) / audit (记录标准审计信息,推荐) / none (不记录历史,性能最优)。 |
process-definition-cache-limit |
缓存流程定义的数量。高并发场景下建议设置一个较大的值(如 -1 表示无限制),避免频繁从数据库加载。 |
mail-server-host/port |
配置 SMTP 服务器,用于在流程中自动发送邮件通知。 |
⚔️ Flowable vs Camunda
| 对比维度 | Flowable | Camunda | 适用场景建议 |
|---|---|---|---|
| 性能 | 大规模并发下表现更稳定 | 中等规模下响应速度略快 | 高并发、大规模场景下优先考虑 Flowable。 |
| 动态流程 | 强。原生支持运行时流程变更、加/减签,适应业务频繁调整的场景 | 较强。通过扩展 API 支持动态调整 | 业务规则经常变化,需要动态调整流程(如金融、信贷审批)的项目,Flowable 更灵活。 |
| 工具链 | 完整(Modeler、Admin、IDM) | 更完整(Cockpit、Modeler、Tasklist),监控和运维体验更佳 | 如果需要开箱即用的可视化监控和管理后台,Camunda 的 Cockpit 体验更好。 |
| API 设计 | API 更丰富,对自定义场景(如动态加签、回退)的支持更直接 | API 稳定但相对保守 | 中小型项目,追求快速、稳定、工具链完善,Camunda 可能更合适。 |
选择建议:
- 首选 Flowable :项目需要高性能 、灵活的流程变更能力,或希望从 Activiti 平滑升级。
- 首选 Camunda :项目流程稳定,不需要太多动态变更 ,但极度看重可视化监控和运维工具。
💡 关键技术难点与避坑指南
- 动态流程变更:支持运行时动态修改流程定义,但在并发或事务边界处易产生状态不一致,建议用独立的事务进行流程变更操作。
- 高并发下的性能瓶颈 :高并发下大量操作集中在
ACT_RU_*运行时表,需优化索引,并开启异步执行器缓解数据库压力。 - 分布式事务与最终一致性 :流程与业务数据操作需保持一致性,推荐使用 "消息+本地事件表" 的模式,通过 Flowable 的异步服务任务(Service Task)触发,实现最终一致性。
- 版本控制与灰度发布:新流程上线时,旧流程的实例可能还在运行。Flowable 的版本控制机制可以确保新旧实例各自运行在正确的流程定义版本上。
- 复杂的"中国式"审批:实现动态加签、驳回至任意节点、会签等复杂功能,需深度定制,可参考网上成熟的解决方案。
- 流程设计器与实际执行不一致:设计器使用不当可能导致运行报错,建议统一工具链,严格校验 BPMN XML 语法。
- 数据库连接池耗尽 :高并发下频繁创建
ProcessEngine会耗尽连接池,务必将其作为单例,并合理配置连接池参数。 - 历史数据膨胀 :
ACT_HI_*表会无限增长,需建立数据归档或定期清理策略,例如按时间分区或定期转移至历史库。
💎 总结
Flowable 是一个功能强大、性能优异且社区活跃的工作流引擎。相比 Camunda 它拥有更灵活的流程变更能力,相比 Activiti 它提供了更活跃的社区支持和持续迭代。
建议在项目中直接使用其 Spring Boot Starter 进行快速集成,并从一开始就关注异步执行器 、历史数据清理 等关键配置。实际开发中,对 ACT_* 系列数据表结构的理解,是解决复杂流程问题和性能调优的必备技能。