当前位置:网站首页>信息安全-威胁检测引擎-常见规则引擎底座性能比较
信息安全-威胁检测引擎-常见规则引擎底座性能比较
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
边栏推荐
- STM32 learning record: play with keys to control buzzer and led
- Research Report on medical toilet industry - market status analysis and development prospect forecast
- Ball Dropping
- ucore lab7
- China medical check valve market trend report, technical dynamic innovation and market forecast
- JS --- BOM details of JS (V)
- Hospital privacy screen Industry Research Report - market status analysis and development prospect forecast
- China potato slicer market trend report, technical dynamic innovation and market forecast
- 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
- LeetCode#118. Yanghui triangle
猜你喜欢
Determine the Photo Position
Learning record: understand systick system timer and write delay function
Optimization method of path problem before dynamic planning
差分(一维,二维,三维) 蓝桥杯三体攻击
Learning records: serial communication and solutions to errors encountered
Eslint--- error: newline required at end of file but not found (EOL last) solution
The wechat red envelope cover designed by the object is free! 16888
学习记录:如何进行PWM 输出
LeetCode#237. Delete nodes in the linked list
ucore lab 2
随机推荐
Cost accounting [17]
Record of force deduction and question brushing
ucorelab4
Es6--- two methods of capturing promise status as failed
Cost accounting [13]
初入Redis
UCORE Lab 1 system software startup process
Research Report on market supply and demand and strategy of China's land incineration plant industry
LeetCode#2062. Count vowel substrings in strings
Learning record: Tim - capacitive key detection
学习记录:USART—串口通讯
C语言是低级和高级的分水岭
HDU - 6024 Building Shops(女生赛)
STM32 learning record: LED light flashes (register version)
Winter vacation daily question - maximum number of balloons
Flex --- detailed explanation of flex layout attributes
Research Report on market supply and demand and strategy of geosynthetics industry in China
Determine the Photo Position
LeetCode#204. Count prime
7-1 懂的都懂 (20 分)