Flowable 与 Camunda 性能对比:怎样设计一次可信的流程引擎压测?
如果只问“Flowable 和 Camunda 谁的 TPS 更高”,这个问题通常没有可信答案。Flowable 与 Camunda 7 都可以作为 Java 引擎嵌入应用、通过关系型数据库保存流程状态;Camunda 8 则通过 Gateway、Zeebe Broker、Partition、Raft 和远程 Job Worker 执行流程。把三者放在一台笔记本上启动一个空流程,得到的数字更多是在比较部署方式,而不是比较企业工作流能力。
可信的流程引擎压测,应先固定业务语义、事务边界、历史级别、数据规模和可靠性目标,再分别测量可持续吞吐量、尾延迟、积压、错误率、资源成本与数据一致性。最终用于选型的不是某个瞬时峰值,而是“在满足企业 SLO 和正确性约束时,系统能够长期稳定维持的负载”。
本文资料更新于 2026 年 7 月,以 Flowable 8.0.0、Camunda 7.24 和 Camunda 8.9 为主要版本基线。Flowable 8.0.0 已升级到 Spring Framework 7、Spring Boot 4 和 Jackson 3;Camunda 7 社区版已结束生命周期;Camunda 8 官方则提供了面向特定工作负载的 Benchmark 工具与容量规划方法。
| 核心概念 | 一句话定义 | 压测中如何使用 |
|---|---|---|
| Offered Load | 压测器计划送入系统的请求速率 | 例如每秒启动 100 个流程实例 |
| Achieved Throughput | 系统实际完成的业务工作量 | 例如每秒完成的流程实例或任务数 |
| Sustainable Throughput | 不持续积压且满足 SLO 的最高稳定吞吐量 | 应作为容量和选型的主要结论 |
| Tail Latency | p95、p99、p99.9 等长尾响应时间 | 避免平均值掩盖少量极慢请求 |
| Backlog | 尚未处理完的任务、作业或事件数量 | 持续增长意味着系统已经过载 |
| Correctness | 无丢失、无重复副作用、状态最终一致 | 性能数字不能以牺牲业务正确性换取 |

图 1:压测器、业务适配层、三类引擎拓扑、存储和可观测系统必须同时纳入测试,不能只统计启动流程接口的响应时间。
一、第一步不是发请求,而是明确在比较哪个 Camunda
1. Flowable 与 Camunda 7 属于相近的关系型数据库路线
Flowable 和 Camunda 7 都源自 Activiti 技术谱系,核心执行状态保存于关系型数据库,并可嵌入 Spring 或 Java 应用。同步执行时,流程状态和本地业务表可以共享事务;异步执行时,后台执行器从数据库获取作业并推进流程。
因此二者可以进行比较接近的“同构压测”:
- 使用相同 JVM、容器资源和数据库规格;
- 使用语义等价的 BPMN 模型;
- 都通过 Java API 或都通过 REST API;
- 使用相同历史级别、变量大小和事务边界;
- 使用等价的同步 Service Task 或异步作业配置;
- 同时监控应用节点、连接池和数据库。
但“同宗同源”不等于默认配置相同。Flowable Async Executor、Camunda 7 Job Executor、历史事件、批量获取、独占作业、数据库方言和查询行为都会改变结果。
2. Camunda 8 是分布式流程编排路线
Camunda 8 的业务应用通过 REST 或 gRPC 连接 Gateway,Broker 负责流程状态,Job Worker 在外部执行企业业务逻辑。Broker 使用分区和复制扩展执行能力,并通过 Exporter 将事件送入二级存储,供 Operate、Tasklist 和查询 API 使用。
这意味着 Camunda 8 至少存在三种延迟:
- 启动命令被 Gateway 接收的延迟;
- 流程在 Broker 内推进并完成的延迟;
- 状态出现在 Operate、Tasklist 或查询 API 中的数据可见延迟。
如果只测第一项,可能得到很高的“流程启动 TPS”,但 Broker、Worker 或 Exporter 已经出现大量积压。Camunda 8 官方的容量文档因此把持续任务吞吐、Backpressure、流程实例 p99、二级存储增长和数据可见延迟都列为关键指标。
3. 一张表确定正确的比较边界
| 对比对象 | 推荐测试类型 | 可以回答的问题 | 不能直接回答的问题 |
|---|---|---|---|
| Flowable vs Camunda 7 | 同构引擎压测 | 相同 Java/RDBMS 条件下谁更符合当前业务模型 | 谁更适合大规模分布式编排 |
| Flowable vs Camunda 8 | 端到端方案压测 | 哪种架构在目标 SLO、可用性和成本下更合适 | 单个引擎方法调用谁更快 |
| Camunda 7 vs Camunda 8 | 迁移容量压测 | 新架构需要多少 Broker、Worker、分区和存储 | 数据库原地升级后的性能变化 |
| 三者空流程压测 | 微型基线 | 驱动器上限、网络和框架固定成本 | 真实审批或业务流程容量 |
公平不等于把三套软件强行部署成相同形态。可信测试既要提供“相同硬件预算”的结果,也要提供“符合各自生产架构”的结果。
二、为什么网上常见的流程引擎性能数字不可信
1. 只测空流程,忽略真实节点成本
一个只有开始事件和结束事件的流程,主要测量 XML 解析缓存、命令框架和数据库写入固定成本。真实企业流程还可能包含:
- 5~30 个 Service Task 或 User Task;
- 会签、并行网关和多实例;
- 条件表达式、DMN 决策和监听器;
- 消息、定时器、子流程和调用活动;
- 表单、候选人、权限和业务规则;
- 2 KB、20 KB 甚至更大的流程变量;
- 历史、审计、操作日志和查询索引。
Camunda 8 官方参考场景使用一个信用卡争议处理流程和约 11 KB Payload,并指出每秒 1 个根流程实例会产生约 101 个任务。这个例子说明“流程实例每秒”和“任务每秒”不是同一个容量单位。
2. 把同步调用与异步处理混为一谈
Flowable 或 Camunda 7 的同步 Service Task 可以在启动流程的调用线程中连续完成;Camunda 8 的 Service Task 通常需要 Worker 通过网络激活和完成 Job。如果只统计启动接口延迟,前者可能把业务执行时间算入请求,后者只统计命令接收时间。
因此必须同时报告:
- Command Latency:API 命令被接受的时间;
- Engine Latency:流程状态推进到目标节点的时间;
- Business Cycle Time:从业务请求进入到最终结果可用的时间;
- Visibility Latency:结果在任务列表或查询 API 中可见的时间。
3. 历史级别不一致
Flowable 官方文档明确说明,History Level 为 none 时运行性能最高;audit 是默认级别;full 会记录更多变量更新和细节,因此最慢。Camunda 7 同样提供 none、activity、audit 和 full 等历史级别。
一个引擎关闭历史、另一个保留完整审计,得出的差异没有选型意义。审批、金融和政务场景通常不能为了压测数字关闭审计,因此至少要提供“最小历史基线”和“生产审计配置”两组结果。
4. 数据库和持久化保证不一致
以下配置看似属于基础设施,实际上会直接决定流程 TPS:
- PostgreSQL、MySQL、Oracle、SQL Server 的版本和参数;
- 本地 NVMe、网络云盘或分布式存储;
- fsync、WAL、Redo Log 和同步复制策略;
- 连接池大小、隔离级别和事务超时;
- 索引、统计信息、表膨胀和历史数据量;
- Camunda 8 的分区数、副本数和二级存储类型;
- 数据库与引擎是否跨可用区。
如果一个方案使用内存 H2,另一个使用三副本持久化集群,结果只能说明可靠性成本不同。
三、怎样建立可复现的流程工作负载矩阵
不要只准备一个 BPMN 文件。企业选型至少需要五类工作负载,每类回答不同问题。

图 2:从直通流程、异步服务、人工审批、事件等待到高并发扇出,逐级暴露数据库、执行器、Worker、分区和查询链路瓶颈。
| 编号 | 工作负载 | 建议模型 | 主要观察点 |
|---|---|---|---|
| W0 | 空流程基线 | Start → End | 驱动器、网络和框架固定开销 |
| W1 | 直通服务编排 | 10 个轻量 Service Task | 引擎推进速度、事务时间、任务吞吐 |
| W2 | 异步服务编排 | 10 个异步任务,每个模拟 20~200 ms | 作业获取、Worker 并发、重试和积压 |
| W3 | 人工审批 | 3 个 User Task,含候选人和表单变量 | 创建、查询、签收、完成和历史查询 |
| W4 | 事件驱动 | 消息、定时器、边界事件、子流程 | 事件订阅、定时扫描、相关性和恢复 |
| W5 | 并行与会签 | 20 路多实例,汇聚后继续 | 热点实例、乐观锁、分区和扇出能力 |
| W6 | 大变量与审计 | 2 KB、20 KB、100 KB 三档 Payload | 序列化、网络、日志、存储和查询成本 |
1. BPMN 语义相同还不够,业务实现也要等价
Service Task 的实现应采用可控的 Stub,不要在第一轮就接入真实 ERP、邮件或支付系统。Stub 至少支持:
- 固定延迟和随机延迟;
- 指定错误率和超时率;
- 幂等键校验;
- 可选 CPU 计算和数据库写入;
- 记录接收、开始、完成和重试时间。
第二轮再替换为真实接口或其性能等价服务。这样既能定位引擎瓶颈,也能评估完整业务链路。
2. 变量和历史数据必须分层
建议每个模型至少运行以下组合:
| 维度 | 基线档 | 生产档 | 压力档 |
|---|---|---|---|
| Payload | 2 KB | 20 KB | 100 KB |
| 历史 | none 或最小 | audit | full |
| 活跃实例 | 1 万 | 10 万 | 100 万 |
| 历史实例 | 空库 | 100 万 | 1000 万 |
| 租户 | 单租户 | 20 租户 | 200 租户 |
| 候选人/权限 | 无 | 生产规模 | 高基数权限 |
高历史数据量尤其重要。新建空库上的任务查询可能很快,但上线几年后的 ACT_HI_*、授权表和二级索引规模完全不同。
四、怎样设计负载阶段,才能找到可持续吞吐量
1. 使用开放负载模型,而不是让慢系统自动少发请求
Closed Model 中,每个虚拟用户完成一次请求后才发下一次。当系统变慢时,请求速率会自动下降,看起来错误率不高,实际上压测器已经替系统限流。
容量测试更适合 Open Model:按固定到达率启动业务,不等待前一个请求完成。Grafana k6 的 constant-arrival-rate 就是这种模型;如果预分配虚拟用户不足,k6 会产生 dropped_iterations,因此压测报告必须同时检查压测器是否真的送达了目标负载。
2. 一次完整压测至少包含六个阶段

图 3:预热、阶梯加压、稳定平台、峰值冲击、恢复和长稳测试分别回答不同问题,不能用一次短时峰值代替。
- 预热:10~20 分钟,让 JVM JIT、缓存、连接池和数据库 Buffer Cache 进入稳定状态;
- 阶梯加压:每 10 分钟提高 20%~30% 到达率,寻找吞吐拐点;
- 稳定平台:在候选容量下持续 30~60 分钟,确认积压不增长;
- 峰值冲击:模拟整点批量启动、月末审批或消息洪峰;
- 恢复测试:停止新增流量,观察积压清空和延迟恢复速度;
- 长稳测试:持续 4~24 小时,暴露 GC、连接泄漏、磁盘增长和历史清理问题。
Camunda 8 的 c8b 工具可以根据 Backpressure 自动调整启动速率,这很适合发现集群上限。但做厂商中立对比时,还应增加固定到达率测试;否则自动降速可能掩盖“目标流量没有真正送入系统”。
3. 防止 Coordinated Omission 美化尾延迟
如果系统暂停 30 秒,而压测器在这 30 秒里只记录一个慢请求,就会漏掉本应到达的其他请求,p99 被严重美化。HdrHistogram 提供带 Expected Interval 的记录方式,可对这种 Coordinated Omission 进行修正。
流程引擎压测应保留原始时间戳或高动态范围直方图,至少报告 p50、p95、p99、p99.9 和最大值,不应只报告平均响应时间。
五、Flowable 应该观察和调节哪些参数
Flowable Async Executor 负责获取并执行 Timer 和异步作业。官方文档显示,其线程池、内存队列、每次获取数量、锁时间、重试次数和过期作业恢复周期都可配置。
1. 需要固定并记录的 Flowable 配置
| 配置类别 | 关键项目 | 可能造成的假象 |
|---|---|---|
| 执行线程 | Core Pool、Max Pool、Queue Size | 线程过少导致积压;过多导致数据库争用 |
| 作业获取 | 每批获取数量、等待时间、锁时间 | 批量太小吞吐不足;太大增加锁冲突 |
| 历史 | none、activity、audit、full | 关闭历史会显著减少写入 |
| 数据库 | 连接池、隔离级别、批量写入、索引 | 连接池或数据库先饱和 |
| 流程设计 | Async、Exclusive、多实例 | 同一实例并发可能产生乐观锁 |
| 标识生成 | 默认或 UUID 策略 | 高并发 ID 生成和索引局部性不同 |
Flowable 官方默认示例中,Async Executor 核心线程和最大线程均为 8,队列大小为 100。这些值不是生产环境的通用最优值。可信报告应先跑默认配置,再在明确记录变更的前提下调优,不能只公布调优后的结果。
2. Flowable 的关键运行指标
- ACT_RU_JOB、ACT_RU_TIMER_JOB、ACT_RU_DEADLETTER_JOB 数量和最老作业年龄;
- 作业获取成功率、锁过期、重试和乐观锁异常;
- 流程完成速率、异步任务完成速率和业务周期;
- 数据库提交延迟、锁等待、慢 SQL 和连接池等待;
- JVM CPU、Heap、GC Pause、线程池活动线程和队列长度;
- 历史表增长速度、历史清理吞吐和任务查询 p99。
六、Camunda 7 应该观察和调节哪些参数
Camunda 7 的 Job Executor 将作业处理分为创建、获取和执行三个阶段。异步边界、Timer、独占作业、获取线程和执行线程都会影响吞吐。
1. Camunda 7 不能只看流程启动接口
对同步流程,启动接口可能包含后续 JavaDelegate 的全部执行时间;对异步流程,接口返回时作业只是写入数据库。因此至少要同时观察:
- 启动命令延迟;
- Job Acquisition 延迟;
- 作业创建到开始执行的 Queue Time;
- 作业执行耗时;
- 流程实例最终完成时间;
- 失败作业、Incident 和重试次数。
Camunda 7 官方数据库性能文档也提醒,查询表现取决于实际配置和工作负载,性能改进并不保证。例如任务查询会连接授权表和流程定义表,权限规模及数据库方言都可能成为主要瓶颈。
2. 生命周期状态也属于选型结论
Camunda 7 社区仓库已经归档。即使它在某个存量场景中性能良好,企业报告也应把长期支持、漏洞修复和退出计划作为单独维度,不能把“跑得快”直接等同于“适合新项目”。
七、Camunda 8 应该观察和调节哪些参数
Camunda 8 的瓶颈可能出现在 Client、Gateway、Broker、Worker、Exporter 或二级存储中的任何一层。官方 c8b 工具支持自定义 BPMN、Payload、启动速率、任务完成延迟、Job Type,并集成 Prometheus 和 Grafana。
1. Camunda 8 的关键压测参数
| 组件 | 关键参数 | 需要观察的信号 |
|---|---|---|
| Gateway | 副本数、连接、REST/gRPC | 请求延迟、错误率、限流 |
| Broker | 节点、分区、副本、CPU、磁盘 | Backpressure、处理速率、复制延迟 |
| Worker | 实例数、线程、Max Jobs Active、超时 | 激活速率、完成速率、重试 |
| Exporter | 批次、并发、目标存储 | Export Lag、写入失败和积压 |
| 二级存储 | Elasticsearch/OpenSearch/RDBMS | 数据可见延迟、查询 p99、磁盘增长 |
| Payload | 变量大小和更新频率 | 网络、Broker 状态、导出和索引放大 |
2. 不能把 Backpressure 当成普通错误率
Backpressure 是系统主动拒绝或推迟新工作以保护集群的机制。Camunda 8 官方 Benchmark 文档把低于 10% 作为寻找可持续上限时的参考,但生产 SLO 往往需要更低。
测试报告应分别给出:
- 0%~0.5% Backpressure 下的生产建议容量;
- 不超过 10% Backpressure 的极限探索容量;
- Backpressure 出现后 p99、积压和恢复时间;
- Process Start 与 Job Completion 的速率差。
如果启动速率持续高于任务完成速率,即使启动命令仍然成功,系统内部也已经开始欠债。
八、哪些指标必须进入最终压测报告

图 4:可信容量位于吞吐拐点之前;进入饱和区后,完成吞吐不再增长,而 p99、积压和资源压力快速上升。
1. 业务层指标
- 每秒启动、完成的流程实例数;
- 每秒创建、完成的 Service Task、User Task 和 Job 数;
- 端到端流程周期 p50、p95、p99;
- 用户任务创建到可查询、可领取的延迟;
- 消息发布到相关流程恢复的延迟;
- Timer 到期到实际触发的偏差;
- 批量会签、加签、回退等业务操作的完成时间。
2. 正确性指标
- 请求数、已接受命令数、完成实例数能否对账;
- 是否存在丢失实例、孤儿任务和无法解释的挂起;
- 外部副作用是否重复执行;
- 重试后业务数据与流程状态是否一致;
- 故障恢复后是否出现重复消息或重复审批;
- 历史、任务列表和运行状态是否最终一致。
3. 系统与成本指标
- CPU、内存、GC Pause、线程和容器 Throttling;
- 数据库 QPS、事务、锁等待、连接池和 Buffer Cache;
- 磁盘 IOPS、吞吐、延迟、容量增长和网络流量;
- Broker、Worker、Exporter 与查询存储的积压;
- 单位成本:每百万任务所需 vCPU 小时、存储和数据库成本。
Prometheus 官方文档指出,多实例聚合延迟时不能直接平均各节点预计算的百分位数。应使用可聚合的 Histogram,再通过 histogram_quantile 计算整体 p95 或 p99。
九、怎样定义“通过”,而不是测试后再挑好看的数字
压测前先写验收门槛。例如:
| 指标 | 示例门槛 | 说明 |
|---|---|---|
| 可持续任务吞吐 | ≥ 500 tasks/s | 连续 60 分钟 |
| 流程完成 p99 | < 2 秒 | W1 直通服务模型 |
| 用户任务可见 p99 | < 3 秒 | 包含任务列表或查询链路 |
| 错误率 | < 0.1% | 排除主动注入的业务错误 |
| Backpressure | 生产档 < 0.5% | 极限探索可单独放宽 |
| Backlog 斜率 | 稳态不持续增长 | 观察最老任务年龄 |
| 数据正确性 | 100% 对账 | 不允许丢失或无法解释的重复 |
| 恢复时间 | < 15 分钟 | 峰值结束后清空积压 |
可持续吞吐量可以定义为:
在指定时间窗口内,同时满足错误率、p99、积压斜率、正确性、Backpressure 和资源水位限制时,系统能够维持的最高固定到达率。
这样做可以防止测试结束后只挑最高 TPS,而忽略已经失控的长尾延迟和队列。
十、一套可以直接执行的企业压测方案
1. 轨道 A:同构引擎能力
适用于 Flowable 与 Camunda 7。
- 相同 Java 版本、JVM 参数、应用实例数和容器资源;
- 相同 PostgreSQL 版本、规格、网络、参数和初始数据;
- 相同 BPMN 语义、Payload、历史级别和 API 方式;
- 先测同步 W1,再测异步 W2、人工 W3 和并行 W5;
- 先跑默认配置,再做有记录的线程池、批量和索引调优;
- 每个负载点至少重复 3 次,报告中位数和离散程度。
这条轨道回答“在相近关系型数据库架构中,哪个引擎更适合当前 Java 应用”。
2. 轨道 B:生产架构端到端能力
适用于 Flowable、Camunda 7 和 Camunda 8 的企业选型。
- 为每个方案设计符合其生产模式的高可用拓扑;
- 给定相同总硬件预算和相同业务 SLO;
- 测量从业务入口到最终状态可查询的完整周期;
- 注入节点重启、数据库切换、Broker/Worker 故障和网络延迟;
- 对比吞吐、p99、恢复、正确性、运维复杂度和单位成本。
这条轨道回答“企业购买同等资源和可靠性后,哪套方案更适合业务目标”。
3. 轨道 C:真实平台业务回放
流程引擎通常只是低代码平台的一部分。以云程低代码开发平台为例,生产链路还包含表单、组织权限、业务规则、门户待办、消息、附件和业务数据库。最终 PoC 应从脱敏生产日志中提取流程类型、到达率、Payload 分布、并发会签规模和查询比例,按时间序列回放,而不是只运行合成 BPMN。

这条轨道回答“引擎进入真实平台后,用户看到的体验和整体容量是否达标”。
十一、如何阅读最终结果,避免得出错误结论
1. 最高峰值不等于可持续容量
在短时间内,内存队列、连接池和操作系统缓存可以吸收流量。真正的容量拐点通常表现为:
- Offered Load 继续上升,但 Completed Throughput 不再增长;
- p99 和最大延迟快速增加;
- 最老作业年龄、Backlog 或 Export Lag 持续增长;
- CPU Throttling、数据库锁等待或磁盘延迟升高;
- 停止加压后需要很长时间才能恢复。
生产建议容量应留在拐点之前,并保留峰值、故障和版本升级余量。
2. 资源利用率低不一定代表还有容量
CPU 只有 40%,系统仍可能受单分区、数据库锁、连接池、网络往返或 Worker Job Type 分配限制。必须把业务吞吐、队列、线程、数据库和分布式组件指标放在同一时间轴上分析。
3. 一次胜负不足以支持选型
每个场景至少重复三次,保持测试顺序随机化或重新初始化环境,并记录:
- 代码 Commit、镜像 Digest、配置文件;
- BPMN、Payload、Stub 版本;
- 基础设施规格、区域和存储类别;
- 压测器规格、时间同步和网络位置;
- 原始指标、日志、查询计划和异常;
- 调优前后差异以及变更理由。
如果报告无法让另一支团队复现,结论就不应被称为基准测试。

浙公网安备 33010602011771号