在项目中,我们经常会涉及到使用规则引擎,例如:报警的场景、计算折扣等场景。在前几年的金融行业工作的时候,我主要从事的是大数据风控这块的行业,使用规则引擎的场景就更多了,因此这两天有空,正好把之前涉及到的内容都整理一下。我们之前使用的就是QLExpress这块规则引擎。
我们为什么选择QLExpress来构建整体的规则引擎呢?
在之前的大数据风控这块我们也调研过很多的规则引擎,例如:drools、Urule、QLExpress等等,在这里大概的介绍下这3款主要的产品。
1、drools规则引擎
这块规则引擎是基于java的,是IBM这边的产品,当初在调研的时候综合体验了一下有如下几点体会:
1、文档大部分都是英文的 2、自定义规则的话是写在file文件里面,基于此点上线比较麻烦。 3、部署起来需单独部署第三方系统,并且当时没有测试并发情况
备注:上诉对drools的印象大概是8年前的一个记忆,现如今的话应该改善很大了。
2、Urule规则引擎
这个规则引擎是一个国产厂家构建的,有前端可视化规则配置,但是后端不开源。在调研这款规则引擎的时候,给了我们很大的感触,因为使用规则引擎的人一般都是风控业务人员,不应该让他们去了解代码是如何构建的,只需要他们可以可视化,很直观的配置规则引擎即可。
3、QLExpress规则引擎
这个规则引擎本身就是java写的,可以很方便的在java里面对规则进行执行。并且是阿里开源的,所以在调研的时候我们就决定深入的使用这个规则引擎。到现在还记得这款规则引擎为我们带来的好处:
1、QLExpress本身就是java写的,对于java开发人员比较友好。 2、QLExpress是阿里巴巴开源的,在淘宝内部有大量的使用经验。 3、QLExpress可以根据具体的业务逻辑构建一个自研的规则引擎系统,实现业务人员在web系统里面进行可视化配置,就可以让这个规则在生产环境里面直接生效(这块主要是借鉴的Urule的思路,后来我们开发的规则引擎配置和测试运行系统都是模仿URule的。)
在经过一系列的调研之后,我们确定使用的了QLExpress。
QLExpress有哪些特点呢?
在qlexpress的官网的里面提到过它有这些特点:
1、线程安全,引擎运算过程中的产生的临时变量都是threadlocal类型。 2、高效执行,比较耗时的脚本编译过程可以缓存在本地机器,运行时的临时变量创建采用了缓冲池的技术,和groovy性能相当。 3、弱类型脚本语言,和groovy,javascript语法类似,虽然比强类型脚本语言要慢一些,但是使业务的灵活度大大增强。 4、安全控制,可以通过设置相关运行参数,预防死循环、高危系统api调用等情况。 5、代码精简,依赖最小,250k的jar包适合所有java的运行环境,在android系统的低端pos机也得到广泛运用。
那么接下来我们就挨个进行QLExpress的功能,并且后面会给大家真实介绍下QLExpress的实际应用。
接下来先编写一个QLExpress的helloword案例。
一、创建一个maven的项目,并且引入依赖
<dependency> <groupId>com.alibaba</groupId> <artifactId>QLExpress</artifactId> <version>3.3.0</version> </dependency>
二、创建一个QlExpress的java
package com.qlexpress.demo; import javax.annotation.PostConstruct; import javax.annotation.PreDestroy; import org.junit.Test; import com.ql.util.express.DefaultContext; import com.ql.util.express.ExpressRunner; import lombok.extern.slf4j.Slf4j; /** * 这里演示qlexpress * * @author Administrator * */ @Slf4j public class QLExpressDemo { @Test public void test1() throws Exception { // 定义规则引擎执行器,qlexpress中的规则引擎执行的时候都是在这个ExpressRunner里面执行的 ExpressRunner runner = new ExpressRunner(); // 定义规则,规则引擎需要执行的是规则,所以我们需要去定义一个可执行的规则,这里的a + b + c 代表的是a,b,c三个变量进行相加 String expressQL = "a + b + c"; // 接收变量值,这里的变量值一般是以一个hashmap的结构给传递进来的,一般这里的参数我们直接是从外部进行组装传递进来的。 DefaultContext<String, Object> params = new DefaultContext<String, Object>(); params.put("a", 1); params.put("b", 2); params.put("c", 3); // 有了规则,有了变量,那么就需要去执行对应的规则 Object result = runner.execute(expressQL, params, null, true, true); log.info("本次规则执行的结果是:{}", result); } }
然后运行一下:看下结果
上面案例的逻辑是计算a+b+c的求和运算,从上图我们也得到了规则的执行结果为6。
备注下:
1、在上面案例的runner里面,我们可以看到runner.executor方法,他的实际方法是:
runner.execute(expressString, context, errorList, isCache, isTrace)
第5个参数的isTrace代表的是是否打印出来规则引擎的执行逻辑过程。即这里的代码:
如果我们选择true的话,那么在执行的时候就会执行上图被圈中的部分,如果是false的话,则不打印上图被圈中的部分:
在调试或者生产环境中我们一般都建议把这里打开,这样如果规则运行出现问题,我们可以根据日志打印的逻辑进行规则推算。
还没有评论,来说两句吧...