在日常的开发过程中,经常会遇到一些串行或者并行的业务流程问题,而业务之间不必存在相关性。
在这样的场景下,使用策略和模板模式的结合可以很好的解决这个问题,但是使用编码的方式会使得文件太多,在业务的部分环节可以这样操作,在项目角度就无法一眼洞穿其中的环节和逻辑。
1.2.1 简介
liteflow 是一个轻巧而且强大的规则引擎,能够实现开箱即用,可以在短时间内就可以完成复杂的规则编排,下图是 liteflow 的整体架构。liteflow 支持较多的规则文件格式,比如 xml/json/yaml, 对于规则文件的存储方式可以有sql/zk/nacos/apollo 等。
通过LiteFlow我们可以把业务逻辑都定义到不同组件之中,然后使用简洁的规则文件来串联整个流程,从而实现复杂的业务逻辑。
LiteFlow主要特性如下:
LiteFlowX 规则引擎官方网址:https://liteflow.yomahub.com
1.2.2 架构原理
liteflow 的使用是从获取上下文开始的,通过数据上下文来解析对应的规则文件,通过 liteflow 执行器来执行对应的链路,每个链路上都有需要执行的业务 node(即节点组件,可以支持多种语言脚本, groovy/js/python/lua等), 各个业务node 之间是独立的。
LiteFlow 还拥有自己的IDEA插件LiteFlowX,通过该插件能支持规则文件的智能提示、语法高亮、组件与规则文件之间的跳转及LiteFlow工具箱等功能,强烈建议大家安装下。
接下来我们学习下规则表达式,也就是规则文件的编写,入门表达式非常简单,但这对使用LiteFlow非常有帮助
1.4.1 串行编排
当我们想要依次执行a、b、c、d四个组件时,直接使用THEN关键字即可。
1.4.2 并行编排
如果想并行执行a、b、c三个组件的话,可以使用WHEN关键字。
1.4.3 选择编排
如果想实现代码中的switch逻辑的话,例如通过a组件的返回结果进行判断,如果返回的是组件名称b的话则执行b组件,可以使用SWITCH关键字。
1.4.4 条件编排
如果想实现代码中的if逻辑的话,例如当x组件返回为true时执行a,可以使用IF关键字
如果想实现if的三元运算符逻辑的话,例如x组件返回为true时执行a组件,返回为false时执行b组件,可以编写如下规则文件。
如果想实现if else逻辑的话,可以使用ELSE关键字,和上面实现效果等价。
如果想实现else if逻辑的话,可以使用ELIF关键字。
1.4.5 使用子流程
当某些流程比较复杂时,我们可以定义子流程,然后在主流程中引用,这样逻辑会比较清晰。
例如我们有如下子流程,执行C、D组件。
然后我们直接在主流程中引用子流程即可。
#=## 1.5 使用
1.5.1 配置
接下来修改配置文件application.yml,配置好LiteFlow的规则文件;在 liteflow 中,需要配置的内容有规则文件地址,节点重试(执行报错时可以进行重试,类似于 spring-retry), 流程并行执行线程池参数配置,流程的请求ID配置。
1.5.2 组件
1.5.2.1 组件讲解
首先我们需要定义好各个组件,普通组件需要继承NodeComponent并实现process()方法,还需设置@Component注解的名称,可以通过重写isAccess方法来决定是否执行该组件;
liteflow 的组件在规则文件中即对应的节点,组件对应的种类有很多,具体的如下所示:
1.5.2.2 组件使用
较特殊组件,比如用于判断是按国内运费计算规则来计算还是境外规则的条件组件,需要继承NodeSwitchComponent并实现processSwitch()方法;
定义好组件之后就可以通过规则文件将所有流程连接起来了
最后在Controller中添加接口,然后调用FlowExecutor类的执行方法即可;
1.5.3 数据上下文
我们平时在写复杂代码时,后面一步经常会用到前面一步的结果,然而使用LiteFlow之后,组件里并没有参数传递,那么各个流程中参数是这么处理的?其实是LiteFlow中有个上下文的概念,流程中的所有数据都统一存放在此,比如上面的PriceContext类;
在 liteflow 中,数据上下文的概念非常重要,上下文对象起到参数传递的作用,因为不同业务需要的输入输出参数是不同的,所以上下文非常的重要。
执行流程时,需要传递el文件,初始化参数以及上下文对象,这里的上下文可以设置多个
LiteflowResponse response = flowExecutor.execute2Resp(“chain1”, 流程初始参数, CustomContext.class);
因为上下文传入的是一个 class 类型参数,流程参数是可以传入参数的,一般情况下是在第一个节点中,将传入参数设置到上下文对象中。
使用电商场景的应用,订单完成后,进行积分的发放,消息发送,同时并行发送短信和邮件。
在订单完成之后异步执行,传递参数并执行相应的规则流程。
在正式处理业务流程之前,需要先进行数据的预处理,将流程入参转转换成上下文对象,方便参数的传递和设置。
在具体的业务处理环节,以积分发放为例,可以获取上下文对象进行业务操作,同时也可以重写 isAccess 方法,来判断是否处理该节点。
如上所示,具体的业务流程都可以抽象成一个 node 节点,存放在 test_flow.el.xml 中进行行
地址:https://liteflow.cc/pages/5816c5/
你可以像以下那样构造一个chain,由于和规则定义的没冲突。你也可以和规则文件结合起来用。当build的时候,如果没有则添加,如果有则修改。
值得提一下的是,由于用构造模式是一个链路一个链路的添加,如果你用了子流程,如果chain1依赖chain2,那么chain2要先构建。否则会报错。