别再用硬编码写业务流程了,试试这款轻量级流程编排框架

前言

在每一个公司的系统中,总有一些拥有复杂业务逻辑的系统,这些系统承载着核心业务逻辑,几乎每一个需求都和这些核心业务有关,这些核心业务业务逻辑冗长,涉及内部逻辑运算,缓存操做,持久化操做,外部资源调取,内部其余系统RPC调用等等。时间一长,项目几经易手,维护的成本得就会愈来愈高。各类硬代码判断,分支条件愈来愈多。代码的抽象,复用率也愈来愈低,各个模块之间的耦合度很高。一小段逻辑的变更,会影响到其余模块,须要进行完整回归测试来验证。如要灵活改变业务流程的顺序,则要进行代码大改动进行抽象,从新写方法。实时热变动业务流程?几乎很难实现。java

开源解决方案

说到流程引擎,开源界有大名鼎鼎的老牌开源软件JBPM,也有近几年很是流行的Activiti和Flowable。他们都是基于BPM协议,能够作到基于角色任务的流传,逻辑的流转。而且不少基于BPM协议的编辑工具都能作可视化的编辑。git

但今天我要介绍的,是一款轻量级的流程编排框架——Liteflow。spring

Liteflow主要致力于逻辑驱动的编排。能够知足于大部分的生产业务场景。和以上著名的开源流程引擎相比,虽然不如他们那么全面,可是胜在轻量,高性能和极少的学习成本。并且这些项目都是国外开源项目,集成起来相对比较重,文档本地化也作的不够好。Liteflow拥有完善的本地文档和使用范例。能帮助你的核心系统变得更加灵活,更加易扩展。是一个解耦你系统的利器。缓存

https://gitee.com/bryan31/lit...

file

Liteflow框架的做用

Liteflow就是为解耦复杂逻辑而生,若是你要对复杂业务逻辑进行新写或者重构,用liteflow最合适不过。它是一个轻量,快速的组件式流程引擎框架,组件编排,帮助解耦业务代码,让每个业务片断都是一个组件。springboot

使用Liteflow,你须要去把复杂的业务逻辑按代码片断拆分红一个个小组件,并定义一个规则流程配置。这样,全部的组件,就能按照你的规则配置去进行复杂的流转。同时Liteflow支持规则文件的热加载,即时完成修改生效。并提供多种持久化规则的方式的扩展。框架

Liteflow的设计原则

Liteflow是基于工做台模式进行设计的,何谓工做台模式?ide

n个工人按照必定顺序围着一张工做台,按顺序各自生产零件,生产的零件最终能组装成一个机器,每一个工人只须要完成本身手中零件的生产,而无需知道其余工人生产的内容。每个工人生产所须要的资源都从工做台上拿取,若是工做台上有生产所必须的资源,则就进行生产,如果没有,就等到有这个资源。每一个工人所作好的零件,也都放在工做台上。spring-boot

这个模式有几个好处:工具

  • 每一个工人无需和其余工人进行沟通。工人只须要关心本身的工做内容和工做台上的资源。这样就作到了每一个工人之间的解耦和无差别性。
  • 即使是工人之间调换位置,工人的工做内容和关心的资源没有任何变化。这样就保证了每一个工人的稳定性。
  • 若是是指派某个工人去其余的工做台,工人的工做内容和须要的资源依旧没有任何变化,这样就作到了工人的可复用性。
  • 由于每一个工人不须要和其余工人沟通,因此能够在生产任务进行时进行实时工位更改:替换,插入,撤掉一些工人,这样生产任务也能实时的被更改。这样就保证了整个生产任务的灵活性。

这个模式映射到Liteflow框架里,工人就是组件,工人坐的顺序就是流程配置,工做台就是上下文,资源就是参数,最终组装的这个机器就是这个业务。正由于有这些特性,因此Liteflow能作到统一解耦的组件和灵活的装配。性能

springboot里快速配置

Liteflow支持了springboot的自动装配,固然Liteflow也为非springboot和非spring的项目也提供了支持,这里仅以springboot项目为示例进行介绍:

依赖最新的依赖包:

<dependency>
  <groupId>com.yomahub</groupId>
  <artifactId>liteflow-spring-boot-starter</artifactId>
  <version>2.3.3</version>
</dependency>

配置上规则路径:

liteflow.rule-source=config/flow.xml

定义组件

Liteflow但愿用户把复杂逻辑拆分红一个个可复用的组件,因此你得定义你的组件,组件的定义很简单,你须要继承NodeComponent类,而后实现process 方法就行,如下为示例:

@Component("test")
public class TestComponent extends NodeComponent {

 @Override
 public void process() {
  Slot slot = this.getSlot();//slot为这个请求的上下文
  //这里为你的业务处理逻辑
 }
}

这里会有童鞋问,个人业务方法须要入参和出参怎么办,如何传递呢?

Liteflow为每一个线程都自动分配了惟一的一个slot,能够理解为上下文。想想上面说的那个模型,每一个组件不须要和其余组件进行信息互通,所须要的参数从slot里取就是了,同时,执行完业务逻辑以后,把结果也放入slot里。因此每一个组件都是独立的无参构造,这样就消除了每一个组件的差别性。

这里的slot能贯穿全部组件,每个组件均可以访问到slot里全部的数据。固然每一个请求之间的slot,Liteflow作了严格的隔离,不用担忧数据会串的问题。

Liteflow提供的默认Slot是一个弱类型的对象,这里建议使用者本身定义一个值对象,只须要继承AbsSlot类,即可成为你本身的Slot。更加贴合业务。

组件除了必需要实现的process 方法,还有几个可选实现:

isAccess:表示是否进入该节点,能够用于业务参数的预先判断

isContinueOnError:表示出错是否继续往下执行下一个组件,默认为false

isEnd:表示是否当即结束整个流程 ,默认为false,也能够在业务日志里根据业务判断来调用this.setIsEnd(true)来结束整个流程。

@Component("test")
public class TestComponent extends NodeComponent {

 @Override
 public void process() {
  Slot slot = this.getSlot();//slot为这个请求的上下文
  //这里为你的业务处理逻辑
 }
  
  @Override
 public boolean isAccess() {
  Slot slot = this.getSlot();
  //这里作你的参数检查,若是没获取到必须的业务参数,就不会进入该组件
  boolean checkResult = true;//模拟检查结果为true
  return checkResult;
 }
  
  @Override
 public boolean isContinueOnError() {
  return super.isContinueOnError();//默认为false
 }
  
  @Override
 public boolean isEnd() {
  return super.isEnd();//默认为false
 }
}

你只需定义你的业务组件,以后,在启动时,Liteflow会自动扫描到你定义的全部组件,并进行加载。

编辑规则文件

实现完了组件以后,你须要定义规则文件,以前规则文件的路径配置在了config/flow.xml中,因此咱们要编辑这个文件。

Liteflow的规则文件定义很是简单好理解。简单的配置,可是能覆盖大部分的应用场景。

先来看一个示例:

<chain name="chain1">
    <then value="a,c"/> 
    <when value="b,d"/> 
    <then value="e,f,g"/>
</chain>

在Liteflow中,定义了then和when两种线程执行方式,then表明串行,上面的示例中,c必需要等a执行完才能执行。when表明并行,上面的示例中,b,d同时执行。而且b,d都执行完了,下面的e,f,g才能挨个顺序执行。

再来看个稍微复杂点的:

<chain name="chain1">
   <then value="a,c(b|d)"/> 
   <then value="e,f,g"/>
</chain>

Liteflow提供了条件组件,这种节点的职责就是路由,根据业务逻辑来路由到b节点仍是d节点。

条件组件的定义示例以下,须要去继承NodeCondComponent这个类,最终返回的b就是最终要路由到的节点

@Component("c")
public class CComponent extends NodeCondComponent {

 @Override
 public String processCond() throws Exception {
    //你的业务逻辑
  return "b";
 }
}

Liteflow容许你编辑嵌套的流程,例子以下:

<chain name="chain1">
  <then value="a,c,strategy1,g"/>
</chain>

<chain name="strategy1">
  <then value="m(m1|m2|strategy2)"/>
</chain>

<chain name="strategy2">
  <then value="q,p(p1|p2)"/>
</chain>

在这个例子中,这3条链路是串起来执行的,在xml里,能够写你的组件id,也能够写流程id。配合以前的例子,是否是能表达的流程就更加丰富了点呢。

以上3个例子涵盖了Liteflow最主要的功能,固然Liteflow还提供一些其余的特性,好比如何进行循环执行,如何打印步骤,而且Liteflow还提供了一个简易的监控模块,用于统计你的组件执行状况。这里就不一一介绍了。具体你能够点击Liteflow的Gitee主页进行查看:

https://gitee.com/bryan31/lit...

示例工程

为了方便用户的使用,Liteflow在项目里提供了一个测试用例,你能够直接拿来跑:

file

同时做者还作了一个带简单业务的示例工程,来演示如何具体实践:

https://gitee.com/bryan31/lit...

这个简单业务是一个电商场景的价格计算的案例,如何经过拆分组件来组合不一样的影响价格的业务。而且这个示例工程还提供了一个简单的页面供你们进行调试:

file

最后

在流程编排开源上,国内一直没有特别著名的开源项目。Liteflow的体量虽然没法和业界著名的流程引擎相比,可是在某些场景,的确提供了轻量级的解决方案。而且Liteflow通过了公司生产大流量业务的考验,在稳定性和性能方面有必定保障。但愿Liteflow这个开源框架能帮助到有这方面业务须要的同窗们。

关于我

我是一个开源做者,也是一名内容创做者。「元人部落」是一个坚持作原创的技术科技分享号,会一直分享原创的技术文章,陪你一块儿成长。关注回复liteflow能加入群聊,这里有不少大佬能和你一块儿探讨技术,回答你的问题。

img

相关文章
相关标签/搜索