title |
---|
借助流程引擎降低系统的复杂度! |
作者:Tom哥
公众号:微观技术
博客:https://offercome.cn
人生理念:知道的越多,不知道的越多,努力去学
作为软件架构师,当面对复杂的业务逻辑,我们常用的解决方案就是拆分
- 将一个大的业务域拆分为若干子域
- 将相似业务逻辑抽象成若干组件,并结合 23 种软件设计模式,提升系统扩展性
以流量网关为例:
我们会定义 Filter
接口,子类通过实现 filter()
方法来满足自己的业务逻辑,如:限流逻辑
、鉴权逻辑
等,如果某些业务流程不需要执行该 Filter
组件,我们可以在 isSkip
方法里定义跳出逻辑,直接跳过该组件,继续执行下一个组件。
最后我们定义了这么多的 Filter 组件,通过 Spring 框架扫描优先级注解,完成了组件链的串联。
当然这个编排比较单一,不够灵活。无法实现一些串行
、并行
的自由组合。
比如,我们面对上图这样的业务流程该如何应对?是自己借助 JUC 并发包以及各种 if else 定制化实现流程控制吗?
另外,随着业务后续迭代,这些任务间的关系还会发生变化,每次都去改动代码,违反软件的开闭原则
,很容易发生线上故障。
**🚀 给大家推荐一款轻量级的流程引擎 **
LiteFlow 是一款国产开源的,具有轻量,快速,稳定可编排的组件式规则引擎,帮助我们拆解实现各种复杂的业务逻辑,开箱即用,上手容易。
- 组件定义统一: 所有的逻辑都是组件,为所有的逻辑提供统一化的组件实现方式,小身材,大能量。
- 规则轻量: 基于规则文件来编排流程,学习规则入门只需要5分钟,一看既懂。
- 规则多样化: 规则支持xml、json、yml三种规则文件写法方式,喜欢哪种用哪个。
- 任意编排: 同步异步混编,再复杂的逻辑过程,利用LiteFlow的规则,都是很容易做到的,看规则文件就能知道逻辑是如何运转的。
- 规则能从任意地方加载: 框架中提供本地文件配置源和zk配置源的实现,也提供了扩展接口,您可以把规则存储在任何地方。
- 优雅热刷新机制: 规则变化,无需重启您的应用,即时改变应用的规则。高并发下不会因为刷新规则导致正在执行的规则有任何错乱。
- 支持广泛: 不管你的项目是不是基于Springboot,Spring还是任何其他java框架构建,LiteFlow都能游刃有余。
- JDK支持: 从JDK8到JDK17,统统支持。无需担心JDK版本。
- 脚本语言支持: 可以定义脚本语言节点,支持QLExpress和Groovy两种脚本。未来还会支持更多的脚本语言。
- 规则嵌套支持: 只要你想的出,你可以利用简单的表达式完成多重嵌套的复杂逻辑编排。
- 组件重试支持: 组件可以支持重试,每个组件均可自定义重试配置和指定异常。
- 上下文隔离机制: 可靠的上下文隔离机制,你无需担心高并发情况下的数据串流。
- 声明式组件支持: 你可以让你的任意类秒变组件。
- 详细的步骤信息: 你的链路如何执行的,每个组件耗时多少,报了什么错,一目了然。
- 稳定可靠: 历时2年多的迭代,在各大公司的核心系统上稳定运行。
- 性能卓越: 框架本身几乎不消耗额外性能,性能取决你的组件执行效率。
- 自带简单监控: 框架内自带一个命令行的监控,能够知道每个组件的运行耗时排行。
LiteFlow 设计了非常强大的规则表达式,一切复杂的流程在 LiteFlow 表达式的加持下,都异常丝滑简便。
我们来一起看下 EL 规则的写法
依次执行 a、b、c、d四个组件,用 THEN 关键字
<chain name="chain1">
THEN(a, b, c, d);
</chain>
并行执行a、b、c三个组件,用WHEN
关键字
<chain name="chain1">
WHEN(a, b, c);
</chain>
根据组件 a 的运行结果,选择执行 b、c、d 中的一个,用 SWITCH
关键字
<chain name="chain1">
SWITCH(a).to(b, c, d);
</chain>
条件编排就是变成语言中的 if else,使用 IF 关键字
其中 x 为条件节点,为真的情况下,执行链路就为x->a->c,为假链路就为x->b->c
<chain name="chain1">
THEN(
IF(x, a, b),
c
);
</chain>
比如,我们要实现这样一个复杂的流程
对应的 EL 表达式为:
<chain name="chain1">
IF(x1, a).ELIF(x2, b).ELIF(x3, c).ELIF(x4, d).ELSE(THEN(m, n));
</chain>
当遇到一些复杂的业务,表达式嵌套多层,很不直观,我们可以先定义子流程,然后在主流程中引用。这样逻辑会比较清晰
定义子流程 sub_chain
,串行执行 a、b 两个组件
<chain name="sub_chain">
THEN(a,b);
</chain>
然后,在主流程中引入之前定义的子流程 sub_chain
<chain name="mainChain">
WHEN(
sub_chain,
c,d
);
</chain>
看完介绍是不是很手痒,接下来我们就以一个电商的 订单价格计算 为例子,讲解下 LiteFlow 如何使用
首先,我们看下订单价格计算接口 都涉及哪些业务逻辑,为了快速切入,画了个流程图便于大家理解
毕竟,一图胜千言哈
以 Spring Boot 应用为例,首先在 pom.xml 文件添加下面的依赖
修改 application.yml 配置文件,添加 LiteFlow 的规则文件路径
定义组件,继承 NodeComponent 类 ,并重写 process() 方法,里面实现自己负责的业务逻辑,比如:促销满减计算、会员折扣计算、运费计算等
通过重写 isAccess() 方法来决定是否执行该组件
MemberDiscountCmp 负责会员折扣计算,根据 memberCode 查询会员等级,并获取对应的会员折扣,然后计算订单可以减免多少优惠
PostageCondCmp 组件比较特殊,根据 是否境外购 选择对应的运费计算组件,继承了 NodeSwitchComponent ,并实现了 processSwitch() 方法
其他业务组件 基本类似,就不一一介绍了,感兴趣的同学可以自己看下代码
所有组件实例无缝支持 Spring 框架,通过@Component
注解标识,所有的Bean实例全部交由 Spring 容器统一管理
定义好组件后,接下来就要编写 EL 规则表达式,将所有的流程关联起来
最后,启动 Spring Boot 工程,访问地址:http://localhost:8580/