为什么我们没用Activiti?数环通iPaaS自研流程引擎的决策复盘

news2026/5/8 17:03:00
写在前面每次跟技术同行聊到我们的流程引擎是自研的这个话题对方的第一反应几乎都一样“为什么不用开源的Activiti/Camunda不香吗”说实话我们内部当年做这个决策的时候也纠结了很久。自研意味着更大的投入、更长的周期、更多的坑要自己填。但五年多走下来回过头看这是数环通iPaaS平台做得最正确的技术决策之一。这篇文章想把这个决策过程拆开来讲当初看了哪些方案为什么不合适自研的引擎做成了什么样踩了哪些坑最终的收益到底体现在哪里。市面上的开源流程引擎各有各的但是Activiti / Camunda — BPMN阵营这两个可能是Java生态里知名度最高的流程引擎了。基于BPMN 2.0规范有成熟的流程设计器社区生态丰富。优点BPMN标准规范流程定义可移植有完整的人工审批、会签、加签等能力丰富的事件信号事件、消息事件、定时事件商业版Camunda有不错的监控后台但是这两个引擎的设计初衷是企业内部审批流程——人工任务在流程中占主导节点之间可能间隔数小时甚至数天。所以它们的执行模型是事件驱动 数据库持久化每一步状态。对iPaaS场景来说问题在于性能模型不匹配。iPaaS流程是API调用链一个流程可能调用5-20个外部API全程几秒到几十秒搞定。每一步都做数据库持久化在日均百万执行量下这个IO开销是致命的。流程定义过重。BPMN XML冗长复杂一个简单的触发器→数据转换→调API就要写几十行XML。而iPaaS的流程本质上就是一条数据管道不需要泳道、不需要人工节点。多租户能力弱。Activiti的多租户只是在数据层面隔离并发控制、资源限制、流量管控全部需要自己做。扩展成本高。想加一个连接器调用的节点类型得深入理解它的ServiceTask和JavaDelegate机制跟自有的连接器体系做适配。改造成本不亚于自研。Temporal / Cadence — 工作流编排阵营Temporal原Uber的Cadence项目衍生是这几年的新秀在微服务编排领域口碑很好。优点天然分布式支持集群部署Activity执行自动重试和超时处理支持长时运行工作流几天甚至几个月工作流的持久化和恢复机制很优秀有信号和查询能力但是技术栈依赖重。需要部署独立的Temporal Server集群依赖Cassandra或MySQL ElasticSearch运维成本不低。对于一个本身就是SaaS产品的平台来说多一套基础设施就多一分出问题的概率。编程模型限制。Temporal要求每个Activity是一个独立函数工作流通过代码编排。而iPaaS的流程是用户在前端可视化拖拽出来的是JSON配置驱动的。两种范式之间的转换层会非常厚。国内生态弱。文档、社区支持主要面向英文用户国内SaaS特有的签名算法、认证方式等适配全靠自己。计费困难。SaaS产品需要按执行次数、步骤数计费。Temporal本身不提供这种粒度的度量需要额外开发。Apache Airflow — 数据管道阵营Airflow在数据工程领域是标配DAG调度能力很强。优点DAG定义直观Python代码定义流程调度能力强Cron、依赖调度有成熟的任务重试和告警机制社区庞大Operator丰富但是Python生态。数环通的技术栈是Java引入Airflow意味着混合语言部署增加复杂度。批处理导向。Airflow是为ETL批处理设计的——T1跑、按天调度。iPaaS需要的是实时事件驱动一个钉钉审批通过2秒内触发后续流程。不适合高并发短任务。Airflow一个Worker进程能处理的并发DAG数很有限远达不到iPaaS单节点数千并发的需求。没有可视化编排能力。面向开发者不面向业务用户。Node-RED / n8n — 轻量集成阵营这类工具跟iPaaS最像都是可视化流程编排 连接器生态。优点低代码可视化编排连接器生态丰富n8n 400节点部署简单前端交互设计优秀但是单机模型。Node-RED和n8n都是单进程设计没有集群调度能力。当执行量上去后只能堆机器没有统一的队列和调度。没有租户隔离。作为自部署工具很合适作为多租户SaaS平台的底座完全不行。执行模型太简单。没有暂停恢复、没有并发控制、没有优雅停机。一个流程卡住可能影响整个进程。Node.js性能天花板。在大数据量同步场景下比如一次拉取10万条订单做ETL受限于V8内存和单线程模型。我们需要的引擎长什么样把上面的分析综合下来数环通iPaaS的流程引擎需要满足这些核心诉求需求维度具体要求执行模型内存态运行只在必要时持久化而非每步持久化并发能力单节点支撑数千流程并发执行多租户租户级并发隔离、资源限制、公平调度驱动方式JSON配置驱动支持前端可视化编排扩展能力Handler插件化新增节点类型不改引擎核心运维能力暂停恢复、优雅停机、超时管控计费支持步骤级计数、连接器维度统计重试机制节点级自动重试支持固定间隔和动态间隔并行分支Fork/Join并行执行没有一个开源方案能同时满足上面这些要求。与其在别人的框架上缝缝补补不如从零设计一个专为iPaaS场景优化的轻量执行引擎。自研引擎的核心架构执行模型Handler Chain Step推进引擎的核心执行模型非常简洁。一个流程在运行时由三个核心对象组成FlowInstance流程定义包含一组Handler和它们的连接关系Execution一次流程执行的上下文承载所有运行时数据ExecutionHandler每个节点的执行逻辑通过nextHandler串联成链执行过程就是沿着Handler Chain逐个推进TriggerHandler → ConnectorHandler → DataTransformHandler → ConnectorHandler → EndEvent每一步Step执行完成后Runner检查是否有中断信号没有就推进到下一个Handler// 核心执行循环handler.execute(ec,callback);// 步骤完成后检查中断if(interruptControl.executeInterrupt(ec)){return;// 响应中断信号}// 推进下一步ec.newStep(currentStep.getNextHandler(),...);为什么这么设计而不是状态机状态机的问题是每次状态变迁都要做持久化否则无法恢复这在高频执行场景下是瓶颈。我们的做法是执行过程全部在内存中完成只在中断时才做快照持久化。99%的流程一气呵成跑完不需要任何IO开销。那1%被中断的流程通过Snapshot恢复到其他节点继续执行。并发控制Semaphore 多级水位单机数千并发流程执行最怕的是雪崩。我们设计了一套多级水位的并发控制机制// 6级执行决策1.子流程/恢复执行 → 直接放行skipQueue2.流程维度并发数超限 → 快速失败或排队3.低于安全水位 → 直接执行4.队列中有排队 → 直接排队保证公平性5.达到警告水位 → 快速失败或排队6.组织维度并发超限 → 快速失败或排队底层用Java Semaphore控制许可数publicclassConcurrencyControl{privatefinalSemaphoresemaphore;publicvoidacquire(Executionec){semaphore.acquire();// 获取许可满了就等}publicvoidrelease(Executionec){semaphore.release();// 执行完释放}publicdoublepermitsUsageRate(IntegerpermitsLimits){// (总量-余量)/总量 使用率return(permitsLimits-availablePermits())/permitsLimits;}}更巧妙的是许可数支持通过Nacos动态调整。线上出现性能问题时可以热调整并发上限而不用重启publicvoidchangePermits(intoriginal,inttarget){if(originaltarget){increase(target-original);// 增加许可}else{decrease(original-target);// 逐个回收许可}}排队机制不能排的快速失败能排的入队等待并非所有流程都适合排队。同步API调用用户在等响应的不能排——排10秒用户早超时了。异步的事件触发流程可以排——反正多等几秒用户感知不到。privatebooleanunableEnqueue(Executionec){// 试运行不排队if(ec.getFlow().isTest())returntrue;// 同步API触发不排队if(TriggerTypeEnum.API_MANAGE_TRIGGER.equals(triggerType)!isAsync(ec))returntrue;returnfalse;}排队的流程会做一次快照持久化等资源空闲后由调度器取出恢复执行。这让引擎在高峰期不会崩溃只是响应变慢了一点——降级而不是崩溃。Fork/Join并行不只是多线程那么简单iPaaS流程中经常需要并行执行多个分支——比如同时向钉钉和飞书发通知、“把一批数据拆成多个批次并行推送”。我们实现了Fork/Join模型protectedListExecutionrunForkContext(Executionec,ExecutionForkContextforkContext){for(ExecutionForkRecordrecord:forkContext.getRecords()){ExecutionforkedEcec.fork();// 派生子执行上下文forkedEc.forkStep(record.getCurrentStep().getCurrentHandler(),...);if(isSync){runner.runSync(forkedEc);// 单分支直接同步执行}else{runner.run(forkedEc);// 多分支并行执行}}join(ec.getCurrentStep().getStepId());// 等待所有分支完成}注意这里的优化如果只有一个分支实际不需要并行直接同步执行避免线程切换开销。这是我们在线上发现的——大量并行网关实际只有一条分支另一条被条件过滤掉了如果还做线程派发纯浪费。Fork等待用Semaphore实现Fork时acquire所有分支完成后在JoinGateway中release。简洁且线程安全。步骤级重试失败了不用从头来外部API调用是不稳定的——网络抖动、限流、超时都可能发生。引擎内置了步骤级重试机制// 支持两种重试策略// 1. 固定间隔每隔N秒重试一次// 2. 动态间隔[1s, 3s, 10s] 逐次递增for(intcurExecCountstart;curExecCountstepRetryCount;curExecCount){// 恢复本步骤的上下文ec.putParameter(currentHandler.getName(),parameter);ec.getCurrentStep().setOutput(output);ec.setNextHandler(nextHandler);ec.setError(error);// 重新执行doExecuteHandler(currentHandler,ec,callback);if(ec.getError()null)break;// 成功了就跳出Thread.sleep(interval);// 等待后重试}关键设计点只对外部连接器调用做重试内部逻辑节点不重试。因为内部节点的失败通常是逻辑错误比如字段映射配错重试也不会好。而外部调用的失败大多是瞬时的重试有意义。中断信号机制无侵入的流程控制引擎支持多种中断类型——手动暂停、部署暂停、手动停止、执行失败、排队中断publicenumInterruptTypeEnum{MANUAL_PAUSE,// 用户手动暂停MANUAL_STOP,// 用户手动停止DEPLOY_PAUSE,// 优雅停机暂停EXECUTE_FAILED,// 执行失败QUEUE// 排队等待}中断信号存在本地 Cache中性能考虑执行器在每个步骤间隙检测一次。检测到信号后流程在当前步骤完成后停下来做快照持久化。这套机制的精巧在于——对Handler实现完全透明。写一个新的连接器Handler不需要关心中断逻辑引擎在外层统一处理。这大大降低了开发新节点类型的心智负担。超时监控不让僵尸流程占着资源每300毫秒巡检一次所有运行中的流程超过配置时间默认6小时的直接终结privateJobResultmonitorTimeoutExecutions(){for(Map.EntryString,Executione:executions.entrySet()){if(ec.getRuntime().getDuration()executionTimeout){timeouts.add(ec);}}for(Executionec:timeouts){ec.setError(newIpaasException(ResultCode.EXECUTION_TIMEOUT));complete(ec);// 释放资源}}看似简单但如果用Activiti做这个事情你需要额外部署一个定时任务去查数据库里的运行中流程然后发信号去中断——链路长、延迟高。我们的实现是纯内存操作毫秒级响应。多租户感知每一层都有隔离从并发控制到队列排队引擎的每一层都是租户感知的并发许可全局信号量控制总并发避免单租户打爆整台机器组织级并发限制groupConcurrencyLimit限制单个组织的最大并发数排队公平性队列按组织隔离一个组织排队不影响其他组织计费统计按组织流程维度统计步骤数、连接器调用数这些能力在开源引擎上几乎不可能开箱获得都是自研才能做到这种粒度的嵌入。自研的真实难度说了这么多好处也得诚实地讲讲自研的代价。第一年最痛苦。从执行模型设计、Handler抽象、到线程模型调优前半年基本在反复推翻重来。特别是并发模型——一开始用的是线程池直接submit结果高并发下线程数爆炸。后来改成Semaphore许可模型才稳定下来。边界场景多。Fork/Join看似简单但嵌套ForkFork里面再Fork、Fork某个分支失败另一个还在跑、Fork和中断信号的交互……这些边界场景的组合爆炸每一个都是生产事故的潜在来源。没有参考。用开源方案至少StackOverflow上能搜到别人遇到的问题。自研引擎的坑全世界只有你自己踩过只能靠线上案例一个一个打磨。测试难度大。流程引擎的测试不是简单的单元测试能覆盖的。并发竞态、超时边界、中断时机……这些需要大量的集成测试和混沌工程手段。我们团队前后投入了3人×12个月才把核心引擎打磨到生产级稳定。这不是一个随便试试的投入量。但回报也是实实在在的性能方面单节点稳定支撑2000并发流程执行。如果用Activiti MySQL这套方案同等并发量可能需要3-5倍的机器资源。灵活性方面新增一种节点类型比如CDC触发器、OPC UA协议节点只需要实现ExecutionHandler接口不需要动引擎核心代码。过去三年我们加了十几种新节点类型引擎主循环的代码几乎没改过。运维方面优雅停机、暂停恢复、动态调参、超时管控——这些能力是生产环境的刚需自研可以做到丝滑集成。如果是基于开源方案改造每一个都是大动作。产品差异化排队机制、多级水位降级、租户并发隔离——这些精细化的资源管控能力直接转化为了SaaS产品的卖点“不限量执行” vs “保证SLA”。发版速度遇到线上问题我们能在小时内定位到引擎层面的原因并修复。如果是开源方案得先判断是框架Bug还是自己的使用问题光排查就可能花几天。总结什么时候该自研什么时候不该说到底是否自研流程引擎取决于你的业务场景和引擎的贴合度。建议用开源方案的场景企业内部审批流程Activiti/Camunda很合适数据ETL调度Airflow是最佳选择微服务编排且团队熟悉Temporal上Temporal个人或小团队做集成工具n8n开箱即用建议自研的场景做SaaS平台需要多租户资源隔离高并发短任务秒级执行、万级QPS需要深度定制执行模型配置驱动、非代码驱动流程执行是核心竞争力不是辅助功能团队有足够的工程投入能力对数环通来说流程引擎是整个产品的心脏。它的性能、稳定性、灵活性直接决定了客户体验。这种核心中的核心交给自己掌控是值得的投入。五年打磨下来这个引擎每天稳定执行着千百万条自动化流程支撑着上万家企业的集成需求。它不完美——代码里还有不少待优化的地方——但它是真正为iPaaS场景量身打造的。这就是自研的意义。数环通iPaaS——自研流程引擎驱动的企业级集成平台1000应用连接器亿万级流程执行。了解更多https://www.solinkup.com标签#流程引擎 #iPaaS #Activiti #Camunda #Temporal #自研引擎 #并发控制 #微服务编排 #数环通 #工作流引擎 #企业集成 #低代码平台

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2595302.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SpringBoot-17-MyBatis动态SQL标签之常用标签

文章目录 1 代码1.1 实体User.java1.2 接口UserMapper.java1.3 映射UserMapper.xml1.3.1 标签if1.3.2 标签if和where1.3.3 标签choose和when和otherwise1.4 UserController.java2 常用动态SQL标签2.1 标签set2.1.1 UserMapper.java2.1.2 UserMapper.xml2.1.3 UserController.ja…

wordpress后台更新后 前端没变化的解决方法

使用siteground主机的wordpress网站,会出现更新了网站内容和修改了php模板文件、js文件、css文件、图片文件后,网站没有变化的情况。 不熟悉siteground主机的新手,遇到这个问题,就很抓狂,明明是哪都没操作错误&#x…

网络编程(Modbus进阶)

思维导图 Modbus RTU(先学一点理论) 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议,由 Modicon 公司(现施耐德电气)于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…

UE5 学习系列(二)用户操作界面及介绍

这篇博客是 UE5 学习系列博客的第二篇,在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下: 【Note】:如果你已经完成安装等操作,可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作,重…

IDEA运行Tomcat出现乱码问题解决汇总

最近正值期末周,有很多同学在写期末Java web作业时,运行tomcat出现乱码问题,经过多次解决与研究,我做了如下整理: 原因: IDEA本身编码与tomcat的编码与Windows编码不同导致,Windows 系统控制台…

利用最小二乘法找圆心和半径

#include <iostream> #include <vector> #include <cmath> #include <Eigen/Dense> // 需安装Eigen库用于矩阵运算 // 定义点结构 struct Point { double x, y; Point(double x_, double y_) : x(x_), y(y_) {} }; // 最小二乘法求圆心和半径 …

使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式

一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明&#xff1a;假设每台服务器已…

XML Group端口详解

在XML数据映射过程中&#xff0c;经常需要对数据进行分组聚合操作。例如&#xff0c;当处理包含多个物料明细的XML文件时&#xff0c;可能需要将相同物料号的明细归为一组&#xff0c;或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码&#xff0c;增加了开…

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器的上位机配置操作说明

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器专为工业环境精心打造&#xff0c;完美适配AGV和无人叉车。同时&#xff0c;集成以太网与语音合成技术&#xff0c;为各类高级系统&#xff08;如MES、调度系统、库位管理、立库等&#xff09;提供高效便捷的语音交互体验。 L…

(LeetCode 每日一题) 3442. 奇偶频次间的最大差值 I (哈希、字符串)

题目&#xff1a;3442. 奇偶频次间的最大差值 I 思路 &#xff1a;哈希&#xff0c;时间复杂度0(n)。 用哈希表来记录每个字符串中字符的分布情况&#xff0c;哈希表这里用数组即可实现。 C版本&#xff1a; class Solution { public:int maxDifference(string s) {int a[26]…

【大模型RAG】拍照搜题技术架构速览:三层管道、两级检索、兜底大模型

摘要 拍照搜题系统采用“三层管道&#xff08;多模态 OCR → 语义检索 → 答案渲染&#xff09;、两级检索&#xff08;倒排 BM25 向量 HNSW&#xff09;并以大语言模型兜底”的整体框架&#xff1a; 多模态 OCR 层 将题目图片经过超分、去噪、倾斜校正后&#xff0c;分别用…

【Axure高保真原型】引导弹窗

今天和大家中分享引导弹窗的原型模板&#xff0c;载入页面后&#xff0c;会显示引导弹窗&#xff0c;适用于引导用户使用页面&#xff0c;点击完成后&#xff0c;会显示下一个引导弹窗&#xff0c;直至最后一个引导弹窗完成后进入首页。具体效果可以点击下方视频观看或打开下方…

接口测试中缓存处理策略

在接口测试中&#xff0c;缓存处理策略是一个关键环节&#xff0c;直接影响测试结果的准确性和可靠性。合理的缓存处理策略能够确保测试环境的一致性&#xff0c;避免因缓存数据导致的测试偏差。以下是接口测试中常见的缓存处理策略及其详细说明&#xff1a; 一、缓存处理的核…

龙虎榜——20250610

上证指数放量收阴线&#xff0c;个股多数下跌&#xff0c;盘中受消息影响大幅波动。 深证指数放量收阴线形成顶分型&#xff0c;指数短线有调整的需求&#xff0c;大概需要一两天。 2025年6月10日龙虎榜行业方向分析 1. 金融科技 代表标的&#xff1a;御银股份、雄帝科技 驱动…

观成科技:隐蔽隧道工具Ligolo-ng加密流量分析

1.工具介绍 Ligolo-ng是一款由go编写的高效隧道工具&#xff0c;该工具基于TUN接口实现其功能&#xff0c;利用反向TCP/TLS连接建立一条隐蔽的通信信道&#xff0c;支持使用Let’s Encrypt自动生成证书。Ligolo-ng的通信隐蔽性体现在其支持多种连接方式&#xff0c;适应复杂网…

铭豹扩展坞 USB转网口 突然无法识别解决方法

当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…

未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?

编辑&#xff1a;陈萍萍的公主一点人工一点智能 未来机器人的大脑&#xff1a;如何用神经网络模拟器实现更智能的决策&#xff1f;RWM通过双自回归机制有效解决了复合误差、部分可观测性和随机动力学等关键挑战&#xff0c;在不依赖领域特定归纳偏见的条件下实现了卓越的预测准…

Linux应用开发之网络套接字编程(实例篇)

服务端与客户端单连接 服务端代码 #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #include <pthread.h> …

华为云AI开发平台ModelArts

华为云ModelArts&#xff1a;重塑AI开发流程的“智能引擎”与“创新加速器”&#xff01; 在人工智能浪潮席卷全球的2025年&#xff0c;企业拥抱AI的意愿空前高涨&#xff0c;但技术门槛高、流程复杂、资源投入巨大的现实&#xff0c;却让许多创新构想止步于实验室。数据科学家…

深度学习在微纳光子学中的应用

深度学习在微纳光子学中的主要应用方向 深度学习与微纳光子学的结合主要集中在以下几个方向&#xff1a; 逆向设计 通过神经网络快速预测微纳结构的光学响应&#xff0c;替代传统耗时的数值模拟方法。例如设计超表面、光子晶体等结构。 特征提取与优化 从复杂的光学数据中自…