当前位置:网站首页>信息安全-威胁检测引擎-常见规则引擎底座性能比较
信息安全-威胁检测引擎-常见规则引擎底座性能比较
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
边栏推荐
- Report on the market trend, technological innovation and market forecast of printing and decorative paper in China
- Visual analysis of data related to crawling cat's eye essays "sadness flows upstream into a river" | the most moving film of Guo Jingming's five years
- Matlab comprehensive exercise: application in signal and system
- JS --- detailed explanation of JS DOM (IV)
- Stm32 dossiers d'apprentissage: saisie des applications
- Eslint--- error: newline required at end of file but not found (EOL last) solution
- China's salt water membrane market trend report, technological innovation and market forecast
- 毕业才知道IT专业大学生毕业前必做的1010件事
- Cost accounting [16]
- 用C语言写网页游戏
猜你喜欢
12306: mom, don't worry about me getting the ticket any more (1)
STM32 how to use stlink download program: light LED running light (Library version)
1010 things that college students majoring in it must do before graduation
学习记录:TIM—电容按键检测
ucorelab4
Crawler series of learning while tapping (3): URL de duplication strategy and Implementation
TCP的三次握手与四次挥手
STM32学习记录:LED灯闪烁(寄存器版)
C语言是低级和高级的分水岭
Learning record: USART serial communication
随机推荐
ucorelab4
Cost accounting [21]
LeetCode#62. Different paths
Medical colposcope Industry Research Report - market status analysis and development prospect forecast
Intensive learning notes: Sutton book Chapter III exercise explanation (ex17~ex29)
Record of force deduction and question brushing
毕业才知道IT专业大学生毕业前必做的1010件事
动态规划前路径问题
ucore lab 6
Cost accounting [13]
VS2019初步使用
JS --- BOM details of JS (V)
Research Report on market supply and demand and strategy of China's land incineration plant industry
Market trend report, technical innovation and market forecast of geosynthetic clay liner in China
Cost accounting [18]
LeetCode#198. raid homes and plunder houses
Cost accounting [13]
学习记录:如何进行PWM 输出
SSM框架常用配置文件
0-1背包问题(一)