当前位置:网站首页>信息安全-威胁检测引擎-常见规则引擎底座性能比较
信息安全-威胁检测引擎-常见规则引擎底座性能比较
2022-07-06 09:26:00 【一一空】

近期需要用到规则引擎来做数据处理和威胁检测引擎,所以对市面上常见的集中常见的规则引擎常用的几种技术方案做了调研,我采用同样的规则,
业务规则:
订单金小于100,给予积分0;
订单金额(100,500],给予积分100;
订单金额(500,1000],给予积分500;
订单金额(1000,+&],给予积分1000;
分别采用下面规则引擎执行100万次、1000万次、5000万次,每个场景执行3次取平均值得出如下表格的结果,从性能测试结果来看,groovy胜出,性能最佳。
| 执行次数\规则引擎 | QLExpression (ms) | groovy (ms) | drools (ms) | v8 |
|---|---|---|---|---|
| 100w | 1590 | 171 | 364 | NA |
| 1000w | 12551 | 709 | 3530 | NA |
| 5000w | 60230 | 3516 | 19414 | NA |
由于v8采用js编码,执行性能较低,没有列入其中进行比较;
| 规则引擎 | QLExpression | groovy | drools |
|---|---|---|---|
| 动态规则 | 支持 | 支持 | 支持 |
| 灵活性 | 低 | 高 | 中 |
| 复杂度 | 低 | 高 | 中 |
| 上手 | 快 | 慢 | 慢 |
| 使用广度 | 中 | 中 | 高 |
三种规则引擎都支持动态规则,可以通过提供的api动态扩展规则,灵活性上看groovy和drools支持脚本编写方式,市面上有常见的包装方案;其中QL在中小企业应用较广泛对熟悉java的选手来说基本开箱即用,groovy和drools作为规则引擎在互联网企业应用较多,有一定的学习和培训成本,drools追随者更多适用面积更广泛;
核心的测试代码如下
groovy
/**
* @ClassName GroovyApplication
* @Description: TODO
* @Author ikong
* @Date 2022/5/30
* @Version V1.0
**/
public class GroovyOrderScoreApplication {
private static String BASIC_FILE_DIR_PATH = "/Users/ikong/demo/rule-engine-demo/rule-engine-demo-groovy/";
private static String GROOVY_FILE_DIR_PATH = BASIC_FILE_DIR_PATH + "src/main/resources/groovy/";
private static String GROOVY_ORDER01_SCRIPT = GROOVY_FILE_DIR_PATH + "order01_java.groovy";
private static String GROOVY_G_SCRIPT = "test02_script.groovy";
private static String GROOVY_P_SCRIPT = "test03_param.groovy";
public static void main(String[] args) throws Exception {
executeJava();//groovy 执行java编写的规则代码
}
private static void executeJava() throws Exception {
//方式一调用groovy文件
ClassLoader parent = GroovyOrderScoreApplication.class.getClassLoader();
GroovyClassLoader loader = new GroovyClassLoader(parent);
Class groovyClass = loader.parseClass(new File(GROOVY_ORDER01_SCRIPT));
//得到groovy对象
GroovyObject groovyObject = (GroovyObject) groovyClass.newInstance();
List<Order> orderList = getInitData();
int count = 200000;
long now = System.currentTimeMillis();
for (int j = 0; j < count; j++) {
for (int i = 0; i < orderList.size(); i++) {
Order order = orderList.get(i);
groovyObject.setProperty("order", order);
groovyObject.invokeMethod("apply", null);
}
}
long cost = System.currentTimeMillis() - now;
System.out.println("drools程序执行:" + count + "次,耗时:" + cost + "ms");
}
private static List<Order> getInitData() throws Exception {
List<Order> orderList = new ArrayList<Order>();
DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
{
Order order = new Order();
order.setAmout(80);
order.setBookingDate(df.parse("2015-07-01"));
User user = new User();
user.setLevel(1);
user.setName("Name1");
order.setUser(user);
order.setScore(111);
orderList.add(order);
}
{
Order order = new Order();
order.setAmout(200);
order.setBookingDate(df.parse("2015-07-02"));
User user = new User();
user.setLevel(2);
user.setName("Name2");
order.setUser(user);
orderList.add(order);
}
{
Order order = new Order();
order.setAmout(800);
order.setBookingDate(df.parse("2015-07-03"));
User user = new User();
user.setLevel(3);
user.setName("Name3");
order.setUser(user);
orderList.add(order);
}
{
Order order = new Order();
order.setAmout(1500);
order.setBookingDate(df.parse("2015-07-04"));
User user = new User();
user.setLevel(4);
user.setName("Name4");
order.setUser(user);
orderList.add(order);
}
return orderList;
}
}pom.xml
<dependencies>
<dependency>
<groupId>org.codehaus.groovy</groupId>
<artifactId>groovy-all</artifactId>
<version>3.0.8</version>
<type>pom</type>
</dependency>
<dependency>
<groupId>org.codehaus.groovy</groupId>
<artifactId>groovy</artifactId>
<version>3.0.8</version>
</dependency>
<dependency>
<groupId>org.codehaus.groovy</groupId>
<artifactId>groovy-ant</artifactId>
<version>3.0.8</version>
</dependency>
</dependencies>Drools
/**
* @ClassName DroolsApplication
* @Description: TODO
* @Author ikong
* @Date 2022/5/30
* @Version V1.0
**/
public class DroolsApplication {
/**
* 计算额外积分金额 规则如下: 订单原价金额
* 100以下, 不加分
* 100-500 加100分
* 500-1000 加500分
* 1000 以上 加1000分
*
* @param args
* @throws Exception
*/
public static final void main(final String[] args) throws Exception {
// KieServices is the factory for all KIE services
KieServices ks = KieServices.Factory.get();
// From the kie services, a container is created from the classpath
KieContainer kc = ks.getKieClasspathContainer();
execute(kc);
}
public static void execute(KieContainer kc) throws Exception {
// From the container, a session is created based on
// its definition and configuration in the META-INF/kmodule.xml file
KieSession ksession = kc.newKieSession("point-rulesKS");
List<Order> orderList = getInitData();
for (int i = 0; i < orderList.size(); i++) {
Order o = orderList.get(i);
ksession.insert(o);
ksession.fireAllRules();
}
int count = 200000;
long now = System.currentTimeMillis();
for (int j = 0; j < count; j++) {
for (int i = 0; i < orderList.size(); i++) {
Order o = orderList.get(i);
ksession.insert(o);
ksession.fireAllRules();
}
}
long cost = System.currentTimeMillis() - now;
System.out.println("drools程序执行:" + count + "次,耗时:" + cost + "ms");
ksession.dispose();
}
private static List<Order> getInitData() throws Exception {
List<Order> orderList = new ArrayList<Order>();
DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
{
Order order = new Order();
order.setAmout(80);
order.setBookingDate(df.parse("2015-07-01"));
User user = new User();
user.setLevel(1);
user.setName("Name1");
order.setUser(user);
order.setScore(111);
orderList.add(order);
}
{
Order order = new Order();
order.setAmout(200);
order.setBookingDate(df.parse("2015-07-02"));
User user = new User();
user.setLevel(2);
user.setName("Name2");
order.setUser(user);
orderList.add(order);
}
{
Order order = new Order();
order.setAmout(800);
order.setBookingDate(df.parse("2015-07-03"));
User user = new User();
user.setLevel(3);
user.setName("Name3");
order.setUser(user);
orderList.add(order);
}
{
Order order = new Order();
order.setAmout(1500);
order.setBookingDate(df.parse("2015-07-04"));
User user = new User();
user.setLevel(4);
user.setName("Name4");
order.setUser(user);
orderList.add(order);
}
return orderList;
}
}pom.xml
<dependency>
<groupId>org.drools</groupId>
<artifactId>drools-core</artifactId>
<version>${drools.version}</version>
</dependency>
<dependency>
<groupId>org.drools</groupId>
<artifactId>drools-compiler</artifactId>
<version>${drools.version}</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.3.2</version>
</dependency><properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<drools.version>7.0.0.Final</drools.version>
<java.version>1.8</java.version>
<tomcat.version>8.5.11</tomcat.version>
</properties>QLExpression
public class QLExpressionApplication {
private static ExpressRunner runner = new ExpressRunner();
private static IExpressContext<String, Object> expressContext = new DefaultContext<String, Object>();
public static void main(String[] args) throws Exception {
String expression = "if (o.amout > 1000) return 1000;"
+ " if (o.amout > 500 && o.amout <= 1000) return 500 ;"
+ " if (o.amout > 100 && o.amout <= 500) return 100 ;"
+ " if (o.amout <= 100 ) return 0 ;";
List<Order> orderList = getInitData();
int count = 200000;
long now = System.currentTimeMillis();
for (int j = 0; j < count; j++) {
for (int i = 0; i < orderList.size(); i++) {
Order order = orderList.get(i);
String ret = execute(order, expression);
if (!StringUtils.isEmpty(ret)) {
order.setScore(Integer.valueOf(ret));
}
}
}
long cost = System.currentTimeMillis() - now;
System.out.println("java程序执行:" + count + "次,耗时:" + cost + "ms");
}
public static String execute(Object obj, String expression) throws Exception {
expressContext.put("o", obj);
List<String> errorInfo = new ArrayList<String>();
Object resultObj = runner.execute(expression, expressContext, errorInfo, true, false);
return null == resultObj ? "" : resultObj.toString();
}
private static List<Order> getInitData() throws Exception {
List<Order> orderList = new ArrayList<Order>();
DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
{
Order order = new Order();
order.setAmout(80);
order.setBookingDate(df.parse("2015-07-01"));
User user = new User();
user.setLevel(1);
user.setName("Name1");
order.setUser(user);
orderList.add(order);
}
{
Order order = new Order();
order.setAmout(200);
order.setBookingDate(df.parse("2015-07-02"));
User user = new User();
user.setLevel(2);
user.setName("Name2");
order.setUser(user);
orderList.add(order);
}
{
Order order = new Order();
order.setAmout(800);
order.setBookingDate(df.parse("2015-07-03"));
User user = new User();
user.setLevel(3);
user.setName("Name3");
order.setUser(user);
orderList.add(order);
}
{
Order order = new Order();
order.setAmout(1500);
order.setBookingDate(df.parse("2015-07-04"));
User user = new User();
user.setLevel(4);
user.setName("Name4");
order.setUser(user);
orderList.add(order);
}
return orderList;
}
}pom.xml
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.83</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>QLExpress</artifactId>
<version>3.2.2</version>
</dependency>以上测试均在JDK1.8下完成
本文代码仓库: https://github.com/philip502/rule-engine-demo.git
边栏推荐
- Cost accounting [19]
- STM32学习记录:LED灯闪烁(寄存器版)
- ucore lab7
- MATLAB实例:阶跃函数的两种表达方式
- LeetCode#237. Delete nodes in the linked list
- Market trend report, technical innovation and market forecast of Chinese hospital respiratory humidification equipment
- CS zero foundation introductory learning record
- F - Birthday Cake(山东省赛)
- Cost accounting [21]
- China's earthwork equipment market trend report, technical dynamic innovation and market forecast
猜你喜欢

ucorelab3

Learning record: use stm32f1 watchdog

Jupyter installation and use tutorial

学习记录:STM32F103 时钟系统概述工作原理

洛谷P1102 A-B数对(二分,map,双指针)

学习记录:使用STM32F1看门狗

JS --- detailed explanation of JS facing objects (VI)

1010 things that college students majoring in it must do before graduation

C语言数组的概念

Lab 8 file system
随机推荐
CS zero foundation introductory learning record
China's PCB connector market trend report, technological innovation and market forecast
Market trend report, technical innovation and market forecast of geosynthetic clay liner in China
区间和------离散化
学习记录:STM32F103 时钟系统概述工作原理
LeetCode#53. Maximum subarray sum
JS --- BOM details of JS (V)
csapp shell lab
ucorelab3
Cost accounting [24]
Take you to use wxpy to create your own chat robot (plus wechat interface basic data visualization)
China earth moving machinery market trend report, technical dynamic innovation and market forecast
F - Birthday Cake(山东省赛)
洛谷P1102 A-B数对(二分,map,双指针)
Intensive learning notes: Sutton book Chapter III exercise explanation (ex17~ex29)
JS --- detailed explanation of JS DOM (IV)
JS --- JS function and scope (II)
12306: mom, don't worry about me getting the ticket any more (1)
STM32學習記錄:輸入捕獲應用
LeetCode#118. Yanghui triangle