流程编排框架LiteFlow详解

流程编排框架LiteFlow详解

2023年7月24日发(作者:)

流程编排框架LiteFlow详解流程编排框架LiteFlow详解1. 前⾔在每个公司的系统中,总有⼀些拥有复杂业务逻辑的系统,这些系统承载着核⼼业务逻辑,⼏乎每个需求都和这些核⼼业务有关,这些核⼼业务业务逻辑冗长,涉及内部逻辑运算,缓存操作,持久化操作,外部资源调取,内部其他系统RPC调⽤等等。时间⼀长,项⽬⼏经易⼿,维护的成本得就会越来越⾼。各种硬代码判断,分⽀条件越来越多。代码的抽象,复⽤率也越来越低,各个模块之间的耦合度很⾼。⼀⼩段逻辑的变动,会影响到其他模块,需要进⾏完整回归测试来验证。如要灵活改变业务流程的顺序,则要进⾏代码⼤改动进⾏抽象,重新写⽅法。实时热变更业务流程,⼏乎很难实现。2. 概述liteFlow是⼀个轻量,快速的组件式流程引擎框架/规则引擎,组件编排,组件复⽤,帮助解耦业务代码,让每⼀个业务⽚段都是⼀个优雅的组件,并⽀持热加载规则配置,实现即时修改。项⽬主页请点击:项⽬⽂档请点击:⽰例⼯程请点击:3. 特点复杂业务的解耦编排利器,为所有组件提供统⼀化的实现⽅式基于规则⽂件来编排流程,⽀持xml,json,yml三种规则⽂件写法⽅式框架中提供本地⽂件配置源,zk配置源的实现框架提供⾃定义配置源,只需实现⼀个接⼝,即可从任何地⽅加载配置源⽀持SpringBoot的⾃动装配,也⽀持Spring的配置和⾮Spring的项⽬提供串⾏和并⾏2种模式,提供常见常见的表达式语句可以定义脚本语⾔节点,⽀持QLExpress和Groovy两种脚本组件可以⽀持重试,每个组件均可⾃定义重试配置和指定异常提供⽆级嵌套的显式⼦流程模式,隐式⼦流程模式数据槽隔离机制,在多并发下上下⽂独⽴⽽稳定⽀持优雅平滑热刷新特性对系统损耗极低,可以稳定运⾏在核⼼业务⼤规模的微服务中⾃带简单的监控,能够知道每个组件的运⾏耗时排⾏4. LiteFlow框架的作⽤LiteFlow就是为解耦复杂逻辑⽽⽣,如果你要对复杂业务逻辑进⾏新写或者重构,⽤LiteFlow最合适不过。它是⼀个轻量,快速的组件式流程引擎框架,组件编排,帮助解耦业务代码,让每⼀个业务⽚段都是⼀个组件,并⽀持热加载规则配置,实现即时修改。使⽤LiteFlow,你需要去把复杂的业务逻辑按代码⽚段拆分成⼀个个⼩组件,并定义⼀个规则流程配置。这样,所有的组件,就能按照你的规则配置去进⾏复杂的流转。5. LiteFlow的设计原则LiteFlow是基于⼯作台模式进⾏设计的,何谓⼯作台模式?n个⼯⼈按照⼀定顺序围着⼀张⼯作台,按顺序各⾃⽣产零件,⽣产的零件最终能组装成⼀个机器,每个⼯⼈只需要完成⾃⼰⼿中零件的⽣产,⽽⽆需知道其他⼯⼈⽣产的内容。每⼀个⼯⼈⽣产所需要的资源都从⼯作台上拿取,如果⼯作台上有⽣产所必须的资源,则就进⾏⽣产,若是没有,就等到有这个资源。每个⼯⼈所做好的零件,也都放在⼯作台上。这个模式有⼏个好处:每个⼯⼈⽆需和其他⼯⼈进⾏沟通。⼯⼈只需要关⼼⾃⼰的⼯作内容和⼯作台上的资源。这样就做到了每个⼯⼈之间的解耦和⽆差异性。即便是⼯⼈之间调换位置,⼯⼈的⼯作内容和关⼼的资源没有任何变化。这样就保证了每个⼯⼈的稳定性。如果是指派某个⼯⼈去其他的⼯作台,⼯⼈的⼯作内容和需要的资源依旧没有任何变化,这样就做到了⼯⼈的可复⽤性。因为每个⼯⼈不需要和其他⼯⼈沟通,所以可以在⽣产任务进⾏时进⾏实时⼯位更改:替换,插⼊,撤掉⼀些⼯⼈,这样⽣产任务也能实时的被更改。这样就保证了整个⽣产任务的灵活性。这个模式映射到LiteFlow框架⾥,⼯⼈就是组件,⼯⼈坐的顺序就是流程配置,⼯作台就是上下⽂,资源就是参数,最终组装的这个机器就是这个业务。正因为有这些特性,所以LiteFlow能做到统⼀解耦的组件和灵活的装配。6. LiteFlow不适⽤于场景LiteFlow⾃开源来,经常有⼀些⼩伙伴来问我,如何做⾓⾊任务之间的流转,类似于审批流,A审批完应该是B审批,然后再流转到C⾓⾊。这⾥申明下,LiteFlow只做基于逻辑的流转,⽽不做基于⾓⾊任务的流转。如果你想做基于⾓⾊任务的流转,推荐使⽤flowable,activiti这2个框架。7. LiteFlow适⽤场景LiteFlow适⽤于拥有复杂逻辑的业务,⽐如说价格引擎,下单流程等,这些业务往往都拥有很多步骤,这些步骤完全可以按照业务粒度拆分成⼀个个独⽴的组件,进⾏装配复⽤变更。使⽤LiteFlow,你会得到⼀个灵活度⾼,扩展性很强的系统。因为组件之间相互独⽴,也也可以避免改⼀处⽽动全⾝的这样的风险。8. LiteFlow相⽐于Flowable和ActivitiFlowable和Activiti都是极为优秀的流程引擎框架,其中Flowable的底层也是Activiti,他们除了能做基于任务⾓⾊的流程,也能做基于逻辑的流程,并且他们的基于BPM协议,很多基于BPM协议的编辑⼯具都能为他们可视化编辑流程。LiteFlow和他们相⽐,虽然功能不如他们那么多,但是胜在轻量,⾼性能和极少学习成本上。⽽且这2款都是国外开源,集成起来⽐较重,⽽且⽂档本地化做的也不够好。LiteFlow拥有完善的本地化⽂档和使⽤范例。在⼤部分的场景可以帮助你改善你的系统。9. 实现验证案例基于liteflow-example实现pom⽂件 4.0.0 spring-boot-starter-parent 2.5.6 liteflow-example 0.0.1-SNAPSHOT liteflow-example Demo project for Spring Boot 1.8 3.4 4.1 spring-boot-starter-web spring-boot-starter-test test s commons-lang3 commons-lang3 ${n} s commons-collections4 ${n} b liteflow-spring-boot-starter 2.6.4 spring-boot-starter-thymeleaf spring-boot-starter-test test e junit-vintage-engine tlombok lombok true hutool-all 5.5.4 compile spring-boot-maven-plugin =urce=liteflow/*.xml#-----------------以下⾮必须-----------------##liteflow是否开启,默认为true#=true##liteflow的banner是否开启,默认为true#-banner=true##zkNode的节点,只有使⽤zk作为配置源的时候才起作⽤#-node=/lite-flow/flow##slot的数量,默认值为1024#-size=1024##异步线程最长的等待时间秒(只⽤于when),默认值为15#-max-wait-second=15##异步线程池最⼤线程数,默认为16#-max-workers=16##异步线程池等待队列数,默认为512#-queue-limit=512##是否在启动的时候就解析规则,默认为true#-on-start=true##全局重试次数,默认为0#-count=0##是否⽀持不同类型的加载⽅式混⽤,默认为false#t-multiple-type=false##是否开启监控log打印,默认值为false#-log=true##监控队列存储⼤⼩,默认值为200#-limit=300##监控⼀开始延迟多少执⾏,默认值为300000毫秒,也就是5分钟#=10000##监控⽇志打印每过多少时间执⾏⼀次,默认值为300000毫秒,也就是5分钟#= ActivityReqVOpackage

import

import

import

import

import

Builder;Data;Date;List;;AbsSlot;/** *

活动请求对象 * * @author zrj * @since 2021/11/15 **/@Data@Builderpublic class ActivityReqVO extends AbsSlot { /** *

活动编码 */ private String activityCode; /** *

活动名称 */ private String activityName; /** *

活动开始时间 */ private Date validStartTime; /** *

活动结束时间 */ private Date validEndTime; /** *

活动⼯具 */ private List activityToolsList;}ActivityToolspackage

import

import

Builder;Data;;/** * @author zrj * @since 2021/11/15 **/@Data@Builderpublic class ActivityTools { /** *

活动编码 */ private String activityCode; /** *

活动⼯具编码 */ private String actToolCode; /** *

活动⼯具名称 */ private String actToolName;}ActivityParamCheckCmppackage

import

import

import

import

/** *

活动请求参数校验 * * @author zrj * @since 2021/11/15 **/@Slf4j@Component("activityParamCheckCmp")public class ActivityParamCheckCmp extends NodeComponent { @Override public void process() throws Exception { ("【活动请求参数校验】"); ActivitySlot activitySlot = t(); if (!checkActParam(ivityCode())) { ntLog("活动编码为空异常"); throw new RuntimeException("活动编码为空异常"); } } /** *

参数校验 */ private boolean checkActParam(String code) { if (code == null) { return false; } return true; }}Slf4j;Component;;NodeComponent;ActivitySlot;ActivitySlotInitCmppackage

import

import

import

import

import

/** *

初始化活动数据槽 * * @author zrj * @since 2021/11/15 **/@Slf4j@Component("activitySlotInitCmp")public class ActivitySlotInitCmp extends NodeComponent { @Override public void process() throws Exception { ("【初始化活动数据槽】"); ActivityReqVO req = t().getRequestData(); ActivitySlot activitySlot = t(); ivityCode(ivityCode()); ivityName(ivityName()); ivityToolsList(ivityToolsList()); } /** *

是否进⼊该节点 * * @return boolean */ @Override public boolean isAccess() { ActivityReqVO req = t().getRequestData(); if (req != null) { return true; } else { return false; } }}Slf4j;Component;;NodeComponent;ActivityReqVO;ActivitySlot;ActivityToolsCheckCmppackage

import

import

import

import

import

import List;Slf4j;;NodeComponent;ActivityTools;ActivitySlot;Component;/** *

活动请求参数校验 * * @author zrj * @since 2021/11/15 **/@Slf4j@Component("activityToolsCheckCmp")public class ActivityToolsCheckCmp extends NodeComponent { @Override public void process() throws Exception { ("【活动⼯具校验】"); ActivitySlot activitySlot = t(); List activityToolsList = ivityToolsList(); ntLog("活动流程测试成功"); }}ActivitySlotpackage

import

import

import

import

import

Data;Date;List;;AbsSlot;ActivityTools;/** *

活动数据槽 * * @author zrj * @since 2021/11/15 **/@Datapublic class ActivitySlot extends AbsSlot { /** *

活动编码 */ private String activityCode; /** *

活动名称 */ private String activityName; /** *

活动开始时间 */ private Date validStartTime; /** *

活动结束时间 */ private Date validEndTime; /** *

活动⼯具 */ private List activityToolsList; /** *

步骤⽇志 */ private String printLog;}ActivityControllerpackage

import

import

import

import

import

import

import

import

import

import

import

import List;;DateUtil;FlowExecutor;LiteflowResponse;ActivityReqVO;ActivityTools;ActivitySlot;GetMapping;RequestMapping;RestController;Resource;ArrayList;/** * @author zrj * @since 2021/11/15 **/@RestController@RequestMapping("/activity")public class ActivityController { @Resource private FlowExecutor flowExecutor; @GetMapping("/liteflow") public String liteflow() { ActivityReqVO activityReqVO = builder(); //ActivityReqVO activityReqVO = null; try { LiteflowResponse response = e2Resp("activityFlow", activityReqVO, ); return t().getPrintLog(); } catch (Throwable t) { tackTrace(); return "error"; } } /** *

构建请求对象 */ private ActivityReqVO builder() { List activityToolsList = new ArrayList<>(10); (r().activityCode("2").actToolName("⼤转盘").build()); (r().activityCode("2").actToolName("红包⾬").build()); return r() .activityCode("2") .activityName("双⼗⼀⼤促") .validStartTime(()) .validEndTime(()) .activityToolsList(activityToolsList) .build(); }}2021-11-15 19:05:26.017 INFO 6844 --- [nio-8580-exec-8] tySlotInitCmp : 【初始化活动数据槽】2021-11-15 19:05:26.017 INFO 6844 --- [nio-8580-exec-8] mponent : [33776573532900]:[O]start component[ActivityParamCheckCmp] execution2021-11-15 19:05:26.017 INFO 6844 --- [nio-8580-exec-8] tyParamCheckCmp : 【活动请求参数校验】2021-11-15 19:05:26.017 INFO 6844 --- [nio-8580-exec-8] mponent : [33776573532900]:[O]start component[ActivityToolsCheckCmp] execution2021-11-15 19:05:26.017 INFO 6844 --- [nio-8580-exec-8] tyToolsCheckCmp : 【活动⼯具校验】2021-11-15 19:05:26.017 INFO 6844 --- [nio-8580-exec-8] : [33776573532900]:CHAIN_NAME[activityFlow]activitySlotInitCmp==>activityParamCheckCmp==>activityToolsCheckCmp

发布者:admin,转转请注明出处:http://www.yc00.com/web/1690213287a315774.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信