当前位置:   article > 正文

信息安全-威胁检测引擎-常见规则引擎底座性能比较_规则引擎 drools和 groovy

规则引擎 drools和 groovy

近期需要用到规则引擎来做数据处理和威胁检测引擎,所以对市面上常见的集中常见的规则引擎常用的几种技术方案做了调研,我采用同样的规则,

业务规则:

订单金小于100,给予积分0;

订单金额(100,500],给予积分100;

订单金额(500,1000],给予积分500;

订单金额(1000,+&],给予积分1000;

分别采用下面规则引擎执行100万次、1000万次、5000万次,每个场景执行3次取平均值得出如下表格的结果,从性能测试结果来看,groovy胜出,性能最佳。

常见规则引擎底座性能比较
执行次数\规则引擎

QLExpression 

(ms)

groovy

(ms)

drools

(ms)

v8
100w1590171364NA
1000w125517093530NA
5000w60230  3516 19414NA

由于v8采用js编码,执行性能较低,没有列入其中进行比较;

常见规则引擎底座难以比较
规则引擎

QLExpression 

groovy

drools

动态规则支持支持支持
灵活性
复杂度
上手
使用广度

三种规则引擎都支持动态规则,可以通过提供的api动态扩展规则,灵活性上看groovy和drools支持脚本编写方式,市面上有常见的包装方案;其中QL在中小企业应用较广泛对熟悉java的选手来说基本开箱即用,groovy和drools作为规则引擎在互联网企业应用较多,有一定的学习和培训成本,drools追随者更多适用面积更广泛;

核心的测试代码如下

groovy

  1. /**
  2. * @ClassName GroovyApplication
  3. * @Description: TODO
  4. * @Author ikong
  5. * @Date 2022/5/30
  6. * @Version V1.0
  7. **/
  8. public class GroovyOrderScoreApplication {
  9. private static String BASIC_FILE_DIR_PATH = "/Users/ikong/demo/rule-engine-demo/rule-engine-demo-groovy/";
  10. private static String GROOVY_FILE_DIR_PATH = BASIC_FILE_DIR_PATH + "src/main/resources/groovy/";
  11. private static String GROOVY_ORDER01_SCRIPT = GROOVY_FILE_DIR_PATH + "order01_java.groovy";
  12. private static String GROOVY_G_SCRIPT = "test02_script.groovy";
  13. private static String GROOVY_P_SCRIPT = "test03_param.groovy";
  14. public static void main(String[] args) throws Exception {
  15. executeJava();//groovy 执行java编写的规则代码
  16. }
  17. private static void executeJava() throws Exception {
  18. //方式一调用groovy文件
  19. ClassLoader parent = GroovyOrderScoreApplication.class.getClassLoader();
  20. GroovyClassLoader loader = new GroovyClassLoader(parent);
  21. Class groovyClass = loader.parseClass(new File(GROOVY_ORDER01_SCRIPT));
  22. //得到groovy对象
  23. GroovyObject groovyObject = (GroovyObject) groovyClass.newInstance();
  24. List<Order> orderList = getInitData();
  25. int count = 200000;
  26. long now = System.currentTimeMillis();
  27. for (int j = 0; j < count; j++) {
  28. for (int i = 0; i < orderList.size(); i++) {
  29. Order order = orderList.get(i);
  30. groovyObject.setProperty("order", order);
  31. groovyObject.invokeMethod("apply", null);
  32. }
  33. }
  34. long cost = System.currentTimeMillis() - now;
  35. System.out.println("drools程序执行:" + count + "次,耗时:" + cost + "ms");
  36. }
  37. private static List<Order> getInitData() throws Exception {
  38. List<Order> orderList = new ArrayList<Order>();
  39. DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
  40. {
  41. Order order = new Order();
  42. order.setAmout(80);
  43. order.setBookingDate(df.parse("2015-07-01"));
  44. User user = new User();
  45. user.setLevel(1);
  46. user.setName("Name1");
  47. order.setUser(user);
  48. order.setScore(111);
  49. orderList.add(order);
  50. }
  51. {
  52. Order order = new Order();
  53. order.setAmout(200);
  54. order.setBookingDate(df.parse("2015-07-02"));
  55. User user = new User();
  56. user.setLevel(2);
  57. user.setName("Name2");
  58. order.setUser(user);
  59. orderList.add(order);
  60. }
  61. {
  62. Order order = new Order();
  63. order.setAmout(800);
  64. order.setBookingDate(df.parse("2015-07-03"));
  65. User user = new User();
  66. user.setLevel(3);
  67. user.setName("Name3");
  68. order.setUser(user);
  69. orderList.add(order);
  70. }
  71. {
  72. Order order = new Order();
  73. order.setAmout(1500);
  74. order.setBookingDate(df.parse("2015-07-04"));
  75. User user = new User();
  76. user.setLevel(4);
  77. user.setName("Name4");
  78. order.setUser(user);
  79. orderList.add(order);
  80. }
  81. return orderList;
  82. }
  83. }

pom.xml

  1. <dependencies>
  2. <dependency>
  3. <groupId>org.codehaus.groovy</groupId>
  4. <artifactId>groovy-all</artifactId>
  5. <version>3.0.8</version>
  6. <type>pom</type>
  7. </dependency>
  8. <dependency>
  9. <groupId>org.codehaus.groovy</groupId>
  10. <artifactId>groovy</artifactId>
  11. <version>3.0.8</version>
  12. </dependency>
  13. <dependency>
  14. <groupId>org.codehaus.groovy</groupId>
  15. <artifactId>groovy-ant</artifactId>
  16. <version>3.0.8</version>
  17. </dependency>
  18. </dependencies>

Drools

  1. /**
  2. * @ClassName DroolsApplication
  3. * @Description: TODO
  4. * @Author ikong
  5. * @Date 2022/5/30
  6. * @Version V1.0
  7. **/
  8. public class DroolsApplication {
  9. /**
  10. * 计算额外积分金额 规则如下: 订单原价金额
  11. * 100以下, 不加分
  12. * 100-500 加100分
  13. * 500-1000 加500分
  14. * 1000 以上 加1000分
  15. *
  16. * @param args
  17. * @throws Exception
  18. */
  19. public static final void main(final String[] args) throws Exception {
  20. // KieServices is the factory for all KIE services
  21. KieServices ks = KieServices.Factory.get();
  22. // From the kie services, a container is created from the classpath
  23. KieContainer kc = ks.getKieClasspathContainer();
  24. execute(kc);
  25. }
  26. public static void execute(KieContainer kc) throws Exception {
  27. // From the container, a session is created based on
  28. // its definition and configuration in the META-INF/kmodule.xml file
  29. KieSession ksession = kc.newKieSession("point-rulesKS");
  30. List<Order> orderList = getInitData();
  31. for (int i = 0; i < orderList.size(); i++) {
  32. Order o = orderList.get(i);
  33. ksession.insert(o);
  34. ksession.fireAllRules();
  35. }
  36. int count = 200000;
  37. long now = System.currentTimeMillis();
  38. for (int j = 0; j < count; j++) {
  39. for (int i = 0; i < orderList.size(); i++) {
  40. Order o = orderList.get(i);
  41. ksession.insert(o);
  42. ksession.fireAllRules();
  43. }
  44. }
  45. long cost = System.currentTimeMillis() - now;
  46. System.out.println("drools程序执行:" + count + "次,耗时:" + cost + "ms");
  47. ksession.dispose();
  48. }
  49. private static List<Order> getInitData() throws Exception {
  50. List<Order> orderList = new ArrayList<Order>();
  51. DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
  52. {
  53. Order order = new Order();
  54. order.setAmout(80);
  55. order.setBookingDate(df.parse("2015-07-01"));
  56. User user = new User();
  57. user.setLevel(1);
  58. user.setName("Name1");
  59. order.setUser(user);
  60. order.setScore(111);
  61. orderList.add(order);
  62. }
  63. {
  64. Order order = new Order();
  65. order.setAmout(200);
  66. order.setBookingDate(df.parse("2015-07-02"));
  67. User user = new User();
  68. user.setLevel(2);
  69. user.setName("Name2");
  70. order.setUser(user);
  71. orderList.add(order);
  72. }
  73. {
  74. Order order = new Order();
  75. order.setAmout(800);
  76. order.setBookingDate(df.parse("2015-07-03"));
  77. User user = new User();
  78. user.setLevel(3);
  79. user.setName("Name3");
  80. order.setUser(user);
  81. orderList.add(order);
  82. }
  83. {
  84. Order order = new Order();
  85. order.setAmout(1500);
  86. order.setBookingDate(df.parse("2015-07-04"));
  87. User user = new User();
  88. user.setLevel(4);
  89. user.setName("Name4");
  90. order.setUser(user);
  91. orderList.add(order);
  92. }
  93. return orderList;
  94. }
  95. }

pom.xml

  1. <dependency>
  2. <groupId>org.drools</groupId>
  3. <artifactId>drools-core</artifactId>
  4. <version>${drools.version}</version>
  5. </dependency>
  6. <dependency>
  7. <groupId>org.drools</groupId>
  8. <artifactId>drools-compiler</artifactId>
  9. <version>${drools.version}</version>
  10. </dependency>
  11. <dependency>
  12. <groupId>org.apache.commons</groupId>
  13. <artifactId>commons-lang3</artifactId>
  14. <version>3.3.2</version>
  15. </dependency>
  1. <properties>
  2. <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  3. <maven.compiler.source>1.8</maven.compiler.source>
  4. <maven.compiler.target>1.8</maven.compiler.target>
  5. <drools.version>7.0.0.Final</drools.version>
  6. <java.version>1.8</java.version>
  7. <tomcat.version>8.5.11</tomcat.version>
  8. </properties>

QLExpression

  1. public class QLExpressionApplication {
  2. private static ExpressRunner runner = new ExpressRunner();
  3. private static IExpressContext<String, Object> expressContext = new DefaultContext<String, Object>();
  4. public static void main(String[] args) throws Exception {
  5. String expression = "if (o.amout > 1000) return 1000;"
  6. + " if (o.amout > 500 && o.amout <= 1000) return 500 ;"
  7. + " if (o.amout > 100 && o.amout <= 500) return 100 ;"
  8. + " if (o.amout <= 100 ) return 0 ;";
  9. List<Order> orderList = getInitData();
  10. int count = 200000;
  11. long now = System.currentTimeMillis();
  12. for (int j = 0; j < count; j++) {
  13. for (int i = 0; i < orderList.size(); i++) {
  14. Order order = orderList.get(i);
  15. String ret = execute(order, expression);
  16. if (!StringUtils.isEmpty(ret)) {
  17. order.setScore(Integer.valueOf(ret));
  18. }
  19. }
  20. }
  21. long cost = System.currentTimeMillis() - now;
  22. System.out.println("java程序执行:" + count + "次,耗时:" + cost + "ms");
  23. }
  24. public static String execute(Object obj, String expression) throws Exception {
  25. expressContext.put("o", obj);
  26. List<String> errorInfo = new ArrayList<String>();
  27. Object resultObj = runner.execute(expression, expressContext, errorInfo, true, false);
  28. return null == resultObj ? "" : resultObj.toString();
  29. }
  30. private static List<Order> getInitData() throws Exception {
  31. List<Order> orderList = new ArrayList<Order>();
  32. DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
  33. {
  34. Order order = new Order();
  35. order.setAmout(80);
  36. order.setBookingDate(df.parse("2015-07-01"));
  37. User user = new User();
  38. user.setLevel(1);
  39. user.setName("Name1");
  40. order.setUser(user);
  41. orderList.add(order);
  42. }
  43. {
  44. Order order = new Order();
  45. order.setAmout(200);
  46. order.setBookingDate(df.parse("2015-07-02"));
  47. User user = new User();
  48. user.setLevel(2);
  49. user.setName("Name2");
  50. order.setUser(user);
  51. orderList.add(order);
  52. }
  53. {
  54. Order order = new Order();
  55. order.setAmout(800);
  56. order.setBookingDate(df.parse("2015-07-03"));
  57. User user = new User();
  58. user.setLevel(3);
  59. user.setName("Name3");
  60. order.setUser(user);
  61. orderList.add(order);
  62. }
  63. {
  64. Order order = new Order();
  65. order.setAmout(1500);
  66. order.setBookingDate(df.parse("2015-07-04"));
  67. User user = new User();
  68. user.setLevel(4);
  69. user.setName("Name4");
  70. order.setUser(user);
  71. orderList.add(order);
  72. }
  73. return orderList;
  74. }
  75. }

pom.xml

  1. <dependency>
  2. <groupId>com.alibaba</groupId>
  3. <artifactId>fastjson</artifactId>
  4. <version>1.2.83</version>
  5. </dependency>
  6. <dependency>
  7. <groupId>com.alibaba</groupId>
  8. <artifactId>QLExpress</artifactId>
  9. <version>3.2.2</version>
  10. </dependency>

以上测试均在JDK1.8下完成

本文代码仓库: https://github.com/philip502/rule-engine-demo.git

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/weixin_40725706/article/detail/541428
推荐阅读
相关标签
  

闽ICP备14008679号