规则引擎-学习

规则引擎-学习

Date Created: Mar 16, 2021 5:17 PM
Status: 要学习的

什么是规则引擎?

规则引擎是根据一些算法执行规则的一些列软件系统。

如何理解呢?这面我的理解是:在某写条件下,执行某些任务。

可以看成前面一堆的if/else的判断逻辑,但是执行的方法体,是固定的。(入参不同,执行结果是不同的)。

初略的找了下目前使用较为多的规则引擎框架,其中Drools是最为突出的。还有一个开源项目也做到了类似的功能。

这面简单的分析了下,如有错误的地方,还望指正哈。

规则引擎-学习

说下Spring boot 项目如何引入和使用Drools


  1. 引入依赖

    <!--drools规则引擎-->
    <dependency>
        <groupId>org.drools</groupId>
        <artifactId>drools-core</artifactId>
        <version>7.6.0.Final</version>
    </dependency>
    <dependency>
        <groupId>org.drools</groupId>
        <artifactId>drools-compiler</artifactId>
        <version>7.6.0.Final</version>
    </dependency>
    <dependency>
        <groupId>org.drools</groupId>
        <artifactId>drools-templates</artifactId>
        <version>7.6.0.Final</version>
    </dependency>
    <dependency>
        <groupId>org.kie</groupId>
        <artifactId>kie-api</artifactId>
        <version>7.6.0.Final</version>
    </dependency>
    <dependency>
        <groupId>org.kie</groupId>
        <artifactId>kie-spring</artifactId>
        <version>7.6.0.Final</version>
    </dependency>
    
  2. 引入Drools的配置类

    @Configuration
    public class RuleEngineConfig {
        private static final Logger LOGGER = LoggerFactory.getLogger(RuleEngineConfig.class) ;
        private static final String RULES_PATH = "droolRule/"; //规则文件 存放目录。
        private final KieServices kieServices = KieServices.Factory.get();
        @Bean
        public KieFileSystem kieFileSystem() throws IOException {
            KieFileSystem kieFileSystem = kieServices.newKieFileSystem();
            ResourcePatternResolver resourcePatternResolver = new PathMatchingResourcePatternResolver();
            Resource[] files = resourcePatternResolver.getResources("classpath*:" + RULES_PATH + "*.*");
            String path = null;
            for (Resource file : files) {
                path = RULES_PATH + file.getFilename();
                LOGGER.info("path="+path);
                kieFileSystem.write(ResourceFactory.newClassPathResource(path, "UTF-8"));
            }
            return kieFileSystem;
        }
        @Bean
        public KieContainer kieContainer() throws IOException {
            KieRepository kieRepository = kieServices.getRepository();
            kieRepository.addKieModule(kieRepository::getDefaultReleaseId);
            KieBuilder kieBuilder = kieServices.newKieBuilder(kieFileSystem());
            kieBuilder.buildAll();
            return kieServices.newKieContainer(kieRepository.getDefaultReleaseId());
        }
        @Bean
        public KieBase kieBase() throws IOException {
            return kieContainer().getKieBase();
        }
        @Bean
        public KieSession kieSession() throws IOException {
            return kieContainer().newKieSession();
        }
        @Bean
        public KModuleBeanFactoryPostProcessor kiePostProcessor() {
            return new KModuleBeanFactoryPostProcessor();
        }
    }
    
  3. 添加规则文件

    在资源目录(/resources)下创建保存规则文件的文件夹。命名为droolRule。并创建以 .drl 结尾的文件。

    dialect  "java"
    rule "paramcheck1"
        salience 99 //参数的大小,确定了执行的顺序
        when queryParam : QueryParam(paramId != null && paramSign.equals("+"))
            resultParam : RuleResult()
        then
            final Logger LOGGER = LoggerFactory.getLogger("param-check-one 规则引擎") ;
            LOGGER.info("参数:getParamId="+queryParam.getParamId()+";getParamSign="+queryParam.getParamSign());
            RuleEngineServiceImpl ruleEngineService = new RuleEngineServiceImpl() ;
            ruleEngineService.executeAddRule(queryParam);
            resultParam.setPostCodeResult(true);
    end
    
  4. 剩下的就是一些基本类和使用注意事项了。

    1. 开放一个接口用来做测试使用

      @RequestMapping("/param")
          public void param (){
              QueryParam queryParam1 = new QueryParam() ;
              queryParam1.setParamId("1");
              queryParam1.setParamSign("+");//添加请求参数 用来判断调用哪个规则
              QueryParam queryParam2 = new QueryParam() ;
              queryParam2.setParamId("2");
              queryParam2.setParamSign("-");
              // 入参
              kieSession.insert(queryParam1) ;
              kieSession.insert(queryParam2) ;
              kieSession.insert(this.ruleEngineService) ;
              // 返参
              RuleResult resultParam = new RuleResult() ;
              kieSession.insert(resultParam) ;
              kieSession.fireAllRules();
          }
      

      paramSign节点添加+/- 对应的是 .drl 文件中的when节点信息判断。

    2. 其中的 kieSession.insert(this.ruleEngineService) ; 是将执行方法相关的类也插入了Session中

    用来通过配置文件调用对应方法。

  5. 总结一下流程 首先是添加Service逻辑代码,之后再添加配置文件进行控制,之后再通过接口请求或者其他方法去调用对应方法。


Rule-engine 简单使用


  1. 目前只找到了一个maven依赖 引入client

    <!-- https://mvnrepository.com/artifact/cn.ruleengine/rule-engine-client -->
    <dependency>
        <groupId>cn.ruleengine</groupId>
        <artifactId>rule-engine-client</artifactId>
        <version>2.0</version>
    </dependency>
    
  2. rule-engine-core 需要通过git下载后打成一个jar进行引用。

  3. 之后参考rule-engine-web 项目,将相应内容添加待集成的环境中

  4. 如需配置前端的页面,也可以参考rule-engine-front前端项目进行配置。

  5. 开发流程为需要创建对应数据库和redis等作为配置信息存储,支持动态发布功能。

  6. 在项目不重新发版的前提下,更改规则可以及时生效。对应的函数,还是需要按照对应要求进行更改/添加

  7. 还支持失败重新执行,需要使用对应的注解在函数上进行配置。

上一篇:规则判定


下一篇:(十五)整合 Drools规则引擎,实现高效的业务规则