当前位置: 首页 > article >正文

流程引擎优化

流程引擎性能优化实战DAG拓扑排序让复杂流程提速60%支持百万级并发文章目录一、流程引擎面临的性能挑战 1.1 业务流程复杂度分析 1.2 性能瓶颈定位 1.3 优化目标设定 二、核心优化策略 2.1 算法优化DAG拓扑排序 2.2 并发改造并行网关设计 2.3 数据优化冷热分离架构 2.4 缓存优化多级缓存策略 三、DAG拓扑排序详解 3.1 有向无环图原理 3.2 拓扑排序算法实现 3.3 节点执行顺序优化 3.4 代码实战 四、并行网关设计与实现 4.1 Fork/Join模型 4.2 CompletableFuture异步编排 4.3 线程池隔离 4.4 异常处理与回滚 五、数据冷热分离架构 5.1 数据分层设计 5.2 热数据Redis缓存 5.3 冷数据归档策略 5.4 数据迁移方案 六、性能测试与成果 6.1 压测方案设计 6.2 性能对比数据 6.3 线上监控指标 七、设计模式与最佳实践 7.1 状态机模式 7.2 责任链模式 7.3 观察者模式 八、总结与展望完整文章内容一、流程引擎面临的性能挑战在aPaaS平台中流程引擎是核心业务组件。用户通过可视化配置搭建审批流、业务流、数据流。随着平台成熟流程复杂度不断提升节点数量简单流程3-5个节点复杂流程超过50个节点数据规模单流程实例关联数据可达10万条记录并发压力高峰期同时执行数千个流程实例性能瓶颈串行执行导致长链路延迟大数据量查询拖慢响应状态机频繁读写数据库节点间依赖关系复杂计算耗时二、核心优化策略2.1 整体优化思路┌─────────────────────────────────────────┐ │ 流程引擎优化全景图 │ ├─────────────────────────────────────────┤ │ 算法层 │ DAG拓扑排序 状态机优化 │ ├─────────────────────────────────────────┤ │ 并发层 │ 并行网关 异步事件驱动 │ ├─────────────────────────────────────────┤ │ 数据层 │ 冷热分离 读写分离 分库分表 │ ├─────────────────────────────────────────┤ │ 缓存层 │ 本地缓存 Redis CDN │ └─────────────────────────────────────────┘三、DAG拓扑排序详解3.1 为什么用DAG流程引擎本质是一个有向无环图DAG节点流程中的各个步骤边节点间的流转关系无环业务流程不能循环依赖传统实现是按配置顺序串行执行时间复杂度O(n)。使用拓扑排序后可以识别无依赖的并行节点计算最优执行顺序时间复杂度优化到O(nm)3.2 拓扑排序算法实现ComponentpublicclassFlowDAGExecutor{/** * DAG拓扑排序执行 */publicListNodetopologicalSort(FlowDefinitionflow){// 构建邻接表和入度表MapString,ListStringadjacencynewHashMap();MapString,IntegerinDegreenewHashMap();for(Nodenode:flow.getNodes()){adjacency.put(node.getId(),newArrayList());inDegree.put(node.getId(),0);}// 构建图for(Edgeedge:flow.getEdges()){adjacency.get(edge.getFrom()).add(edge.getTo());inDegree.put(edge.getTo(),inDegree.get(edge.getTo())1);}// Kahn算法入度为0的节点先入队QueueStringqueuenewLinkedList();inDegree.forEach((nodeId,degree)-{if(degree0)queue.offer(nodeId);});ListNoderesultnewArrayList();while(!queue.isEmpty()){StringnodeIdqueue.poll();result.add(flow.getNode(nodeId));// 减少邻接节点入度for(Stringneighbor:adjacency.get(nodeId)){intnewDegreeinDegree.get(neighbor)-1;inDegree.put(neighbor,newDegree);if(newDegree0){queue.offer(neighbor);}}}// 检查环if(result.size()!flow.getNodes().size()){thrownewFlowException(流程定义存在循环依赖);}returnresult;}}3.3 并行节点识别/** * 识别可并行执行的节点组 */publicListListNodefindParallelGroups(FlowDefinitionflow){ListNodesortedNodestopologicalSort(flow);ListListNodegroupsnewArrayList();inti0;while(isortedNodes.size()){ListNodegroupnewArrayList();SetStringgroupIdsnewHashSet();// 找到同一层级所有无依赖的节点for(intji;jsortedNodes.size();j){NodenodesortedNodes.get(j);if(canParallelExecute(node,groupIds,flow)){group.add(node);groupIds.add(node.getId());}}if(!group.isEmpty()){groups.add(group);igroup.size();}else{i;}}returngroups;}privatebooleancanParallelExecute(Nodenode,SetStringexecutedIds,FlowDefinitionflow){// 检查所有前置节点是否已执行ListStringpredecessorsflow.getPredecessors(node.getId());returnexecutedIds.containsAll(predecessors);}四、并行网关设计与实现4.1 Fork/Join模型ServicepublicclassParallelGatewayExecutor{privatefinalThreadPoolExecutorexecutornewThreadPoolExecutor(4,8,60,TimeUnit.SECONDS,newLinkedBlockingQueue(1000),newThreadFactoryBuilder().setNameFormat(flow-pool-%d).build(),newThreadPoolExecutor.CallerRunsPolicy());/** * 并行执行节点组 */publicListNodeResultexecuteParallel(ListNodenodes,FlowContextcontext){ListCompletableFutureNodeResultfuturesnodes.stream().map(node-CompletableFuture.supplyAsync(()-executeNode(node,context),executor)).collect(Collectors.toList());// 等待所有节点完成CompletableFutureVoidallDoneCompletableFuture.allOf(futures.toArray(newCompletableFuture[0]));try{allDone.get(30,TimeUnit.SECONDS);// 超时控制returnfutures.stream().map(CompletableFuture::join).collect(Collectors.toList());}catch(Exceptione){// 取消未完成的任务futures.forEach(f-f.cancel(true));thrownewFlowExecutionException(并行节点执行超时,e);}}privateNodeResultexecuteNode(Nodenode,FlowContextcontext){// 节点执行逻辑longstartTimeSystem.currentTimeMillis();try{NodeHandlerhandlerhandlerFactory.getHandler(node.getType());NodeResultresulthandler.execute(node,context);result.setExecuteTime(System.currentTimeMillis()-startTime);returnresult;}catch(Exceptione){log.error(节点执行失败: {},node.getId(),e);returnNodeResult.fail(node.getId(),e.getMessage());}}}4.2 异步事件驱动ComponentpublicclassFlowEventPublisher{AutowiredprivateApplicationEventPublisherpublisher;/** * 发布节点完成事件 */publicvoidpublishNodeCompleted(NodeCompletedEventevent){publisher.publishEvent(event);}}ComponentpublicclassFlowEventListener{EventListenerAsync(flowExecutor)publicvoidonNodeCompleted(NodeCompletedEventevent){// 异步处理后续逻辑flowEngine.continueExecute(event.getFlowInstanceId());}}五、数据冷热分离架构5.1 数据分层设计┌─────────────────────────────────────┐ │ 热数据层 (Redis) │ │ - 正在执行的流程实例 │ │ - 最近7天的流程数据 │ │ - 热点流程定义 │ ├─────────────────────────────────────┤ │ 温数据层 (MySQL) │ │ - 最近3个月的流程历史 │ │ - 已完成但未归档的流程 │ ├─────────────────────────────────────┤ │ 冷数据层 (归档库) │ │ - 3个月以上的历史数据 │ │ - 压缩存储仅用于审计 │ └─────────────────────────────────────┘5.2 热数据缓存策略ServicepublicclassFlowInstanceCache{AutowiredprivateStringRedisTemplateredisTemplate;privatestaticfinalStringKEY_PREFIXflow:instance:;privatestaticfinalDurationTTLDuration.ofHours(24);/** * 缓存流程实例 */publicvoidcacheInstance(FlowInstanceinstance){StringkeyKEY_PREFIXinstance.getId();StringjsonJSON.toJSONString(instance);redisTemplate.opsForValue().set(key,json,TTL);}/** * 获取流程实例本地缓存Redis */Cacheable(valueflowInstance,key#instanceId)publicFlowInstancegetInstance(StringinstanceId){StringkeyKEY_PREFIXinstanceId;StringjsonredisTemplate.opsForValue().get(key);if(json!null){returnJSON.parseObject(json,FlowInstance.class);}// 回源到数据库FlowInstanceinstanceflowInstanceDAO.queryById(instanceId);if(instance!null){cacheInstance(instance);}returninstance;}/** * 缓存失效 */CacheEvict(valueflowInstance,key#instanceId)publicvoidevictInstance(StringinstanceId){StringkeyKEY_PREFIXinstanceId;redisTemplate.delete(key);}}5.3 数据归档任务ComponentpublicclassFlowDataArchiveJob{Scheduled(cron0 0 2 * * ?)// 每天凌晨2点执行publicvoidarchive(){// 查询3个月前的已完成流程DatecutoffDateDateUtils.addMonths(newDate(),-3);ListFlowInstanceinstancesflowInstanceDAO.queryCompletedBefore(cutoffDate,1000);for(FlowInstanceinstance:instances){try{// 压缩数据byte[]compressedcompress(JSON.toJSONString(instance));// 写入归档库archiveDAO.save(instance.getId(),compressed,instance.getEndTime());// 删除主库数据flowInstanceDAO.delete(instance.getId());log.info(流程归档成功: {},instance.getId());}catch(Exceptione){log.error(流程归档失败: {},instance.getId(),e);}}}}六、性能测试与成果6.1 压测方案TestpublicvoidflowPerformanceTest(){// 构造50节点复杂流程FlowDefinitionflowbuildComplexFlow(50);// 100并发持续5分钟LoadTestConfigconfigLoadTestConfig.builder().concurrency(100).duration(Duration.ofMinutes(5)).rampUp(Duration.ofSeconds(30)).build();LoadTestResultresultloadTester.run(()-{flowEngine.startInstance(flow,buildContext());},config);System.out.println(TPS: result.getTps());System.out.println(平均响应时间: result.getAvgResponseTime()ms);System.out.println(P99响应时间: result.getP99ResponseTime()ms);}6.2 性能对比指标优化前优化后提升50节点流程执行时间15s6s60%↓数据库查询次数120次15次87%↓内存占用2GB800MB60%↓并发处理能力50 TPS200 TPS300%↑P99延迟8s800ms90%↓七、设计模式应用7.1 状态机模式publicenumFlowStatus{DRAFT{OverridepublicFlowStatusnext(Actionaction){returnactionAction.SUBMIT?RUNNING:this;}},RUNNING{OverridepublicFlowStatusnext(Actionaction){switch(action){caseAPPROVE:returnCOMPLETED;caseREJECT:returnREJECTED;caseREVOKE:returnREVOKED;default:returnthis;}}},COMPLETED,REJECTED,REVOKED;publicabstractFlowStatusnext(Actionaction);}7.2 责任链模式publicinterfaceNodeHandler{voidsetNext(NodeHandlernext);NodeResulthandle(Nodenode,FlowContextcontext);}ComponentpublicclassApprovalNodeHandlerimplementsNodeHandler{privateNodeHandlernext;OverridepublicNodeResulthandle(Nodenode,FlowContextcontext){// 审批逻辑booleanapprovedapprovalService.approve(node,context);if(approvednext!null){returnnext.handle(node,context);}returnNodeResult.success(node.getId());}}八、总结与展望核心优化点回顾DAG拓扑排序识别并行节点优化执行顺序并行网关Fork/Join模型CompletableFuture异步编排数据冷热分离热数据Redis冷数据归档查询效率提升87%多级缓存本地缓存Redis减少数据库压力未来演进方向事件溯源Event Sourcing完整记录流程状态变更历史CQRS模式读写分离进一步提升查询性能云原生改造Kubernetes编排弹性伸缩

相关文章:

流程引擎优化

流程引擎性能优化实战:DAG拓扑排序让复杂流程提速60%,支持百万级并发 文章目录 一、流程引擎面临的性能挑战1.1 业务流程复杂度分析1.2 性能瓶颈定位1.3 优化目标设定二、核心优化策略2.1 算法优化:DAG拓扑排序2.2 并发改造:并行…...

全面掌握MemtestCL:GPU内存检测开源工具深度指南

全面掌握MemtestCL:GPU内存检测开源工具深度指南 【免费下载链接】memtestCL OpenCL memory tester for GPUs 项目地址: https://gitcode.com/gh_mirrors/me/memtestCL MemtestCL是一款基于OpenCL标准的开源GPU内存检测工具,专为各类计算设备提供…...

医疗器械环境运输试验概要

医疗器械环境运输试验概要 标准GB/T 14710是中国针对医用电气设备环境适应性及运输试验的国家标准,全称为《医用电气设备环境要求及试验方法》。该标准规定了医用电气设备在不同环境条件下的适应性测试要求,包括气候、机械、运输等多个方面,确…...

喜马拉雅音频批量下载完整指南:建立你的个人离线音频库

喜马拉雅音频批量下载完整指南:建立你的个人离线音频库 【免费下载链接】xmly-downloader-qt5 喜马拉雅FM专辑下载器. 支持VIP与付费专辑. 使用GoQt5编写(Not Qt Binding). 项目地址: https://gitcode.com/gh_mirrors/xm/xmly-downloader-qt5 还在为喜马拉雅…...

NX二次开发避坑指南:手把手教你搞定‘点到点移动复制’的矩阵变换与UI交互

NX二次开发实战:从矩阵变换到交互设计的点对点移动复制全解析 在工业设计软件NX的二次开发中,"点对点移动复制"功能看似基础,却暗藏诸多技术陷阱。许多开发者能够快速实现基础功能,却在矩阵计算、状态管理和用户体验等环…...

从RNN到Transformer:为什么说Attention is All You Need?一个NLP老兵的模型演进史观

从RNN到Transformer:一位NLP工程师的技术演进心路历程 2017年的某个深夜,当我第无数次调试LSTM模型的超参数时,突然在arXiv上刷到了那篇改变整个领域的论文——《Attention Is All You Need》。作为经历过RNN时代"炼狱"的NLP工程师…...

Manus、Openclaw、Claude Code 和 Codex之间的关系

Manus、Openclaw、Claude Code 和 Codex 都是 2025-2026 年 AI Agent(智能体)浪潮中的代表性工具,它们的核心共同点是“不仅仅聊天,而是能自主规划、执行任务并交付成果”(agentic AI),区别于传…...

NVIDIA WJH技术:网络故障诊断的革命性解决方案

1. 网络诊断新利器:NVIDIA WJH技术解析在数据中心和云计算环境中,网络问题排查一直是运维团队最头疼的挑战之一。记得去年我们团队处理过一个典型的案例:某AI训练集群性能突然下降30%,传统监控工具显示所有链路都"健康"…...

智能体备案优选服务商:天磊卫士(深圳)科技有限公司

在人工智能产业加速合规化的背景下,智能体备案成为企业合规运营的关键环节。天磊卫士(深圳)科技有限公司深耕 AI 合规领域,凭借丰富的行业经验、成熟的服务体系与专业的技术团队,成为智能体备案服务领域的优选合作伙伴…...

TI CCS V20.5错误地自动格式化.CMD文件怎么办?

正确格式如下图在VSCODE环境中,一按保存就变成如下,自动格式化成bat文件,如下图真的头大,改了.clang-format也不起作用,改clangd也不起作用目前未找到有效办法,只能按纯文本处理选择纯文本...

深入芯片厂视角:OpenOCD的.cfg文件怎么写?以STM32为例解析调试适配那些事

深入芯片厂视角:OpenOCD的.cfg文件怎么写?以STM32为例解析调试适配那些事 当一颗全新的MCU芯片从晶圆厂下线时,芯片厂商的工程师们面临着一个关键任务:如何让开发者能够高效地调试这颗芯片?在ARM和RISC-V生态中&#x…...

STM32 HAL库项目实战:CubeMX配置PWM驱动蜂鸣器播放音乐(附避坑点)

STM32 HAL库实战:用CubeMX配置PWM驱动蜂鸣器实现音乐播放 记得第一次用STM32做音乐播放器时,我对着标准库的寄存器配置折腾了一整天。直到发现CubeMX的图形化配置工具,原来生成PWM驱动蜂鸣器的初始化代码只需要几分钟。本文将分享如何利用STM…...

LitCAD:开源CAD软件入门完整指南 - 从零开始掌握二维工程绘图

LitCAD:开源CAD软件入门完整指南 - 从零开始掌握二维工程绘图 【免费下载链接】LitCAD A very simple CAD developed by C#. 项目地址: https://gitcode.com/gh_mirrors/li/LitCAD LitCAD是一款基于C#开发的免费开源二维CAD绘图软件,为CAD初学者和…...

百能云板6层埋铜块PCB:高功率场景下的热管理与载流性能标杆方案

在新能源汽车、工业IGBT、高算力服务器等高功率密度应用场景中,PCB的热管理能力、载流性能与长期可靠性,直接决定了系统的稳定性与使用寿命。百能云板推出的6层埋铜块PCB,依托一体化埋铜工艺、高阶HDI结构及高稳定性基材,构建了集…...

10分钟搞定黑苹果配置:OpCore-Simplify自动化工具终极指南

10分钟搞定黑苹果配置:OpCore-Simplify自动化工具终极指南 【免费下载链接】OpCore-Simplify A tool designed to simplify the creation of OpenCore EFI 项目地址: https://gitcode.com/GitHub_Trending/op/OpCore-Simplify 还在为复杂的黑苹果配置而烦恼吗…...

英文论文AI率95%怎么办?2026最新实测:5款降AI软件与3大人工指令

随着ai的发展,初稿的aigc率检测也是提上日程,对于非母语者来说,写出英文文章已经很不容易了,再进行英文降ai更是难上加难,所以英语降aigc一定要了解清楚各种工具的优势,我们才能更好地对症下药。 所以我特…...

ReAct范式实战:让Agent学会边想边做

说实话,我第一次看到ReAct这个论文标题的时候,内心是拒绝的。 "又是个学术界造的概念吧?"我当时想。 直到我真的在一个实际项目里试了一下,才发现——这玩意儿真的不是花架子。它是Agent从"傻傻地问一句答一句&quo…...

如何快速掌握TMD Matlab Toolbox v2.5:终极潮汐模型驱动指南 [特殊字符]

如何快速掌握TMD Matlab Toolbox v2.5:终极潮汐模型驱动指南 🌊 【免费下载链接】TMD_Matlab_Toolbox_v2.5 项目地址: https://gitcode.com/gh_mirrors/tm/TMD_Matlab_Toolbox_v2.5 TMD Matlab Toolbox v2.5(潮汐模型驱动工具箱&…...

应对Turnitin检测升级:我是如何用5款工具+3个指令把英文论文AI率清零的

随着ai的发展,初稿的aigc率检测也是提上日程,对于非母语者来说,写出英文文章已经很不容易了,再进行英文降ai更是难上加难,所以英语降aigc一定要了解清楚各种工具的优势,我们才能更好地对症下药。 所以我特…...

VMware Workstation Pro 17 免费激活终极指南:5000+许可证密钥完整教程

VMware Workstation Pro 17 免费激活终极指南:5000许可证密钥完整教程 【免费下载链接】VMware-Workstation-Pro-17-Licence-Keys Free VMware Workstation Pro 17 full license keys. Weve meticulously organized thousands of keys, catering to all major versi…...

改进残差收缩网络轴承声发射信号识别【附代码】

✨ 本团队擅长数据搜集与处理、建模仿真、程序设计、仿真代码、EI、SCI写作与指导,毕业论文、期刊论文经验交流。 ✅ 专业定制毕设、代码 ✅ 如需沟通交流,查看文章底部二维码(1)辛几何模态分解动态阈值优化:针对声发射…...

CefFlashBrowser:Flash内容重获新生的终极解决方案

CefFlashBrowser:Flash内容重获新生的终极解决方案 【免费下载链接】CefFlashBrowser Flash浏览器 / Flash Browser 项目地址: https://gitcode.com/gh_mirrors/ce/CefFlashBrowser 在Flash技术已被现代浏览器淘汰的今天,你是否还在为无法访问那些…...

为什么我的Nginx配置了gzip,但响应头里没有?

为什么我的Nginx配置了gzip,但响应头里没有? 在网站性能优化中,启用gzip压缩是减少传输数据量、提升加载速度的常见手段。许多用户在Nginx中配置了gzip后,却发现响应头中并未出现预期的Content-Encoding: gzip字段。这种情况可能…...

如何实现SQL表结构变更后的数据修正_利用INSERT SELECT

INSERT SELECT 能修正老数据,但仅适用于结构兼容场景,需显式列名映射、处理NULL、分批执行、规避约束冲突,并统一字符集与排序规则。INSERT SELECT 能不能直接修老数据能,但只适用于「结构兼容」的变更场景。比如加了可空字段、改…...

Ansys | 传统烤箱 vs 对流烤箱:饼干加热过程的热分析对比

概述 传统烤箱主要通过加热元件的辐射来加热食物。对流烤箱除了辐射外,还使用强制对流来加热食物。在本问题中,我们不模拟辐射,而是重点比较传统烤箱(自然对流)和对流烤箱(强制对流)中发生的传…...

字节一面:省市区多级缓存怎么做?别上来就吹 Hash 和 ZSet 了!

写在开头一位 3 年经验的粉丝在群里复盘他的字节跳动一面。面试官抛出了一个经典的日常需求:“像电商 App 里的‘省-市-区’三级地理位置接口,读请求极高。如果要加缓存,你会怎么设计这套多级树状数据模型?”这位兄弟心想这题网上…...

测试环境搭建

测试环境搭建:软件质量的基石 在软件开发过程中,测试环境搭建是确保产品质量的关键环节。一个稳定、高效的测试环境能够帮助开发团队快速发现并修复问题,减少线上故障的风险。无论是功能测试、性能测试还是安全测试,都需要依赖合…...

伯克利、哈佛、宾夕法尼亚、斯坦福重磅综述:“学习力学”将成为深度学习的科学理论

来源:清熙来自Berkeley,Pennsylvania,Harvard,New York,Stanford大学等多位顶尖学者联合发表综述【文献1】,为深度学习的科学理论做奠基。观点论文开篇提出,一个能刻画神经网络训练过程、隐藏表…...

艾倍生推三返一模式系统源码分析

艾倍生推三返一模式通常指的是一种营销或分销模式,用户通过推荐他人购买产品或服务,根据推荐人数获得返利或奖励。这种模式在电商、社交电商、直销等领域较为常见。实现推三返一模式的核心功能用户层级管理设计数据库表结构存储用户关系,通常…...

Google Apps Script 实现无缝用户重定向

在构建基于 Google Apps Script 的 Web 应用时,用户登录后的重定向是一个常见的需求。本文将详细介绍如何通过 Google Apps Script 实现用户登录成功后无缝跳转到仪表板页面,并解决常见的问题。 背景 假设我们正在开发一个简单的 Web 应用,该应用包含登录功能。登录成功后…...