项目中有一些业务场景存在动态调整的情况,所以打算引进一个规则引擎来处理,其实一开始没打算用规则引擎,规则直接用Groovy脚本也能实现;后面经过分析,如果用Groovy脚本直接实现可能这个脚本会非常大,因为存在很多条件判断的情况和组合的情况,所以还是要引进一个开源规则引擎会更好。
通过对比各种规则引擎:Drools、urule、ICE、NoP、liteflow,最终选择了liteflow,主要基于以下原因:
Liteflow规则的处理方式有本地、Redis、Nacos、SQL方式,为了方便集中管理,打算采用SQL方式。
通过使用Liteflow的SQL方式,发现其实不是特别方便,Liteflow的SQL方式是将规则做成行的方式,一行行的解析并拼接成XML进行解析,通过查看数据库很难看到整个流程的全貌,维护起来不太方便。这里自己基于源码liteflow-rule-sql重新封装了一个rule,liteflow的rule是基于SPI机制,所以封装起来还是比较方便。
主要修改了com.yomahub.liteflow.parser.sqlext.SQLXmlELParser这个类。
重新实现了parseMain方法,这个方法能支持加载多个xml content内容。
修改JDBCHelper增加getContents()方法返回多个XML结果给到liteflow解析。
@Override
public void parseMain(List<String> pathList) throws Exception {
List<String> contents = JDBCHelper.getInstance().getContents();
parse(contents);
}
@Override
public String parseCustom() {
return null;
}
添加基于数据库的规则脚本:
CREATE TABLE `liteflow_script` (
`uri` VARCHAR(50) NOT NULL,
`name` VARCHAR(100) NOT NULL COMMENT '脚本名称',
`content` TEXT DEFAULT NULL COMMENT 'XML规则内容',
`app_name` VARCHAR(100) NOT NULL COMMENT '所属应用',
`extend` VARCHAR(100) DEFAULT NULL COMMENT '扩展信息',
`flag` INT(5) DEFAULT '0' COMMENT '状态标记',
`del_flag` INT(5) DEFAULT '0' COMMENT '逻辑删除标记',
`create_by` VARCHAR(40) DEFAULT NULL COMMENT '创建者',
`update_by` VARCHAR(40) DEFAULT NULL COMMENT '更新者',
`create_date` DATETIME NULL DEFAULT NULL COMMENT '创建时间',
`update_date` DATETIME NULL DEFAULT NULL COMMENT '更新时间',
`fk_domain` VARCHAR(100) COLLATE utf8_unicode_ci DEFAULT NULL COMMENT '所属域',
`fk_group` VARCHAR(100) COLLATE utf8_unicode_ci DEFAULT NULL COMMENT '所属部门',
PRIMARY KEY (`uri`)
);
INSERT INTO `liteflow_script` (`uri`, `name`, `content`, `app_name`, `extend`, `flag`, `del_flag`, `create_by`, `update_by`, `create_date`, `update_date`, `fk_domain`, `fk_group`) VALUES ('001', '测试脚本', '\r\n \r\n \r\n \r\n \r\n \r\n THEN(a, b, c, s1); \r\n ', 'ucloud-demoliteflow', NULL, 0, 0, NULL, NULL, '2023-09-14 16:29:03', NULL, NULL, NULL);
groovy脚本不会写的话可以先在IDE工具中添加groovy脚本和XML配置文件,然后将其拷贝到mysql配置中
pom.xml依赖:
其中ucloud-starter-literflowrule-sql是自定义的开发的liteflow-rule规则配置(基于SQL)
<dependency>
<groupId>com.yomahubgroupId>
<artifactId>liteflow-spring-boot-starterartifactId>
<version>2.11.0version>
dependency>
<dependency>
<groupId>com.yomahubgroupId>
<artifactId>liteflow-script-groovyartifactId>
<version>2.11.0version>
dependency>
<dependency>
<groupId>com.ucloudgroupId>
<artifactId>ucloud-starter-liteflowrule-sqlartifactId>
<version>1.0.0-SNAPSHOTversion>
dependency>
创建一些测试类:
cmp下面的是一些spring boot的liteflow组件类(参考liteflow的demo拷贝过来的)。
OrderVO,一个临时的订单类
TestLiteFlowServiceImpl是执行规则的服务,具体内容:
@Slf4j
@Service
public class TestLiteFlowServiceImpl {
@Autowired
private FlowExecutor flowExecutor;
public Object execute(OrderVO orderVO) {
Map<String, Object> params = new HashMap<>();
params.put("order", orderVO);
LiteflowResponse response = flowExecutor.execute2Resp("chain1", params, DefaultContext.class);
log.info("返回结果:{}", response);
return response.getContextBean(DefaultContext.class).getData("res");
}
}
@Autowired
private TestLiteFlowServiceImpl testLiteFlowService;
@Autowired
private FlowExecutor flowExecutor;
@GetMapping("/liteflow")
public ResultVO liteFlow() {
OrderVO orderVO = new OrderVO("订单01", 100, 21);
log.info("req order:", orderVO);
Object resObj = testLiteFlowService.execute(orderVO);
log.info("res order:", orderVO);
return ResultVO.success(resObj);
}
@GetMapping("/reloadLiteFlow")
public ResultVO reloadLiteFlow() {
log.info("刷新配置信息");
flowExecutor.reloadRule();
return ResultVO.success();
}
这个例子的执行过程是:
执行脚本:
http://localhost:6018/test/liteflow
执行结果:
c.u.p.d.controller.TestController : req order:OrderVO(name=订单01, price=100, count=21)
ACmp executed!
BCmp executed!
CCmp executed!
规则数据:chain1, s1
请求数据:[order:OrderVO(name=订单01, price=100, count=21)]
c.u.p.d.controller.TestController :order:OrderVO(name=订单01, price=100, count=21)
修改脚本后刷新脚本:
http://localhost:6018/test/reloadLiteFlow
总体上集成和使用还是比较简单的。
liteflow官网地址:https://liteflow.cc/