2 审批流程引擎选型分析

选型直接影响审批流的开发效率、运行稳定性和运维成本。本章从技术实现角度对比 Activiti、Camunda、Flowable 三大主流开源 BPMN 引擎,并给出轻量级自研引擎的适用边界与决策表。

课程导向:本章结论将直接用于后续章节的原型选型与集成策略。建议在阅读时同步准备一份实际的审批场景需求清单,以便对照决策表进行验证。

2.1 主流开源引擎概览

维度 Activiti 7 Camunda 8 Flowable 6
起源 Alfresco 社区分支 Activiti 核心团队另立 Activiti 作者参与的另一分支
核心版本 7.x(基于 Spring Boot) 8.x(云原生 Zeebe 架构) 6.x(兼容 Tomcat/JBoss)
设计理念 轻量、嵌入 Spring 高吞吐、分布式、可扩展 企业级、历史数据查询丰富
API 风格 REST + Java Bean gRPC + REST(Cloud) REST + Java API
性能特征 单机 200~500 tps 集群数万 tps(Zeebe) 单机 300~800 tps
社区活跃度 中等(转向 Alfresco) 高(独立公司运营) 中等(商业版收费)
LICENSE Apache 2.0 Apache 2.0(社区版) Apache 2.0(社区版)
常见陷阱:Activiti 7 之后核心社区分裂,部分扩展组件已停止维护;选型前务必检查你所需 BPMN 元素(如 DMN 决策表、CMMN 案例管理)在目标版本中是否兼容。

2.2 轻量级自研引擎适用场景

当审批场景满足以下条件时,自研引擎比引入成熟引擎更高效:

  • 流程节点数 ≤ 30:复杂 BPMN 解析成本大于自研维护成本。
  • 无并发复杂网关:独占网关、多实例等需成熟的令牌传递机制。
  • 团队规模 ≤ 5 人:无专职流程引擎运维角色。
  • 部署环境受限:如 ARM 边缘节点、嵌入式设备、无数据库依赖场景。
  • 审批规则极简:仅需顺序、并行、回退、会签四种基本模式。
实现参考:自研引擎核心只需一张 wf_node 表(存储节点类型、前后置关系)和一张 wf_token 表(状态机状态),配合定时任务完成超时转移。后续章节会详细给出这种轻量级引擎的数据库设计与状态机代码。

2.3 选型决策表

决策因素 Activiti 7 Camunda 8 Flowable 6 自研引擎
团队有 Spring 经验 ★★★ ★★☆ ★★★ ★★★★
高吞吐(>500 tps) ★★ ★★★★★ ★★★ ★★
需要 BPMN 全面兼容 ★★★ ★★★★★ ★★★★ ★
运维成本敏感 ★★★ ★★(需 K8s) ★★★ ★★★★★
需 DMN/CMMN 支持 ★(移除) ★★★★★ ★★★ ★

推荐策略:短期 MVP 用自研引擎,中期过渡到 Flowable/Activiti,长期高负载场景采用 Camunda 8 云原生方案。

2.4 集成与调试要点

无论选用哪种引擎,集成时需关注以下常见问题:

  • 数据源冲突:引擎自带数据库表前缀(如 ACT_*、CAM_*),需单独配置数据源隔离。
  • 事务边界:流程实例启动与业务数据持久化应处于同一数据库事务,防止中间状态。
  • 循环回退死锁:设计时需设置最大回退次数,或使用循环检测切面。
  • 性能监控:开启引擎内置的 JMX MBean 或集成 Prometheus 指标暴露。
调试技巧:在开发阶段设置 logging.level.org.activiti.engine=DEBUG(对应引擎名称),可输出令牌流转的详细日志,快速定位节点卡顿原因。

2.5 选型决策流程图

下方 SVG 展示了从团队特征到引擎选择的决策路径:

审批流程引擎选型决策图 团队规模与能力 团队>5人? 高吞吐需求 Camunda 8 (Zeebe) 功能复杂度 Activiti / Flowable 自研轻量引擎 也可处理复杂BPMN 说明 1. 团队>5人且高吞吐 → Camunda 8;2. 团队>5人但低吞吐 → Activiti/Flowable;3. 团队≤5人且功能简单 → 自研;4. 任何团队若需全面BPMN/DMN支持,优先Camunda/Flowable。
关键风险:选型决策不能仅依赖一张图。务必进行 POC 验证,尤其关注 历史数据迁移(原有审批表单与引擎数据模型匹配)和 非功能需求(CPU/内存占用,单机压测结果)。

2.6 常见错误与稳定性优化

  • 错误:为降低集成难度直接使用引擎内置用户/组表,导致与现有 IAM 同步困难。 优化:通过 UserEntityManagerFactory 自定义实现,对接已有用户服务。
  • 错误:未配置作业执行器的线程池上限,高峰期打爆 DB 连接池。 优化:设置 asyncExecutorCorePoolSize 与 asyncExecutorMaxPoolSize 为适当值(经验值:CPU 核数 × 2)。
  • 错误:滥用历史数据表(ACT_HI_*)全量查询,导致 OOM。 优化:定期归档历史流程实例,或使用 Camunda/Flowable 提供的 historyCleanupJob。
  • 错误:自研引擎缺少锁机制,并行节点同时到达导致数据库写冲突。 优化:引入分布式锁(Redis/MySQL GET_LOCK)或乐观锁版本号。
推荐配置示例(Flowable/Activiti 公共):
# 数据源
spring.datasource.url=jdbc:mysql://localhost:3306/flowable?useSSL=false
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver

# 引擎核心
flowable.async-executor-activate=true
flowable.async-executor-core-pool-size=4
flowable.async-executor-max-pool-size=8
flowable.async-executor-keep-alive-time=5000

# 历史清理(每24小时自动清理7天前的数据)
flowable.history-cleanup-after=7d
flowable.history-cleanup-batch-size=100
示例中 flowable 替换为 activiti 或 camunda 可适配对应引擎。