Drools入门

Drools入门

Drools官网

目录

  • Drools简述
  • Drools架构
  • Rate算法
  • 在IDEA中构建一个DEMO
  • 规则动态更新
  • 生产环境中使用Drools需要考虑的问题

Drools简述

  • 规则引擎
    drools是一个开源的规则引擎。世界上本没有路,走的人多了就有路了。JAVA一开始也没有设计模式,但经过各种个样的需求和场景开发,工程师总结了常用场景抽象程设计模式。
    规则引擎也是各种不同的需求场景中总结得出的。一般在系统设计之初会通过代码直接实现一些业务需求,比如用户连续签到3天就送一张优惠券。随着产品不断的发展就会出现一些差异不大的需求,比如将上周送5块钱的优惠券改为10块,显然我们要抽象类似场景做一个通用的功能减少重复工作,同时让业务规则和数据解耦。
    同时规则引擎也是一个专家系统。何为专家系统?简单来说就是专业人员使用的系统,比如系统的运营人员。规则引擎对没有开发能力的人员进行赋能,让专业的人做专业的事。
  • 常见的规则引擎
    • IBM的iLog,商业产品
    • Drools,开源
    • 最近比较火的FLink CEP,开源
    • Easy Rule,开源
    • 阿里的qlexpress,开源

架构

  • KIE(Knowledge Is Everything) 知识就是一切。kie是一个提供业务的自动化和管理的解决方案项目集合


    KIE
  • Drools engine


    Drools engine

    左边是规则,右边是事实(数据)。中间就是执行器(决策引擎)

Rete算法

参考文章

Rete在拉丁文中译为“net”,Rete算法是利用网络筛选对规则匹配进行优化的算法实现。其核心思想是将分离的匹配项根据内容动态构造匹配树,以达到显著降低计算量的效果

在IDEA中构建一个DEMO

  • maven依赖
  
    7.5.0.Final
  
  
    
      org.kie
      kie-api
      ${drools.version}
    
    
      org.drools
      drools-compiler
      ${drools.version}
    
    
      org.drools
      drools-core
      ${drools.version}
       
  
  • 目录要求
idea目录
  • kmodule.xml


    
        
    

  • test.drl
package com.naixuan.rules

import com.naixuan.Applicant;
import com.naixuan.Action;

rule "Is of valid age"
when
  $a: Applicant(age < 18)
then
  $a.setValid(false);
  new Action("执行动作").doSomeThing();//执行动作方式一
  insert(new Action("不合法"));//执行动作方式二
end

rule "send_act"
when
    $a: Action()
then
    $a.doSomeThing();
end
  • 代码

public class App {
    public static void main(String[] args) {
        KieServices kieServices = KieServices.Factory.get();
        //默认自动加载 META-INF/kmodule.xml
        KieContainer kieContainer = kieServices.getKieClasspathContainer();
        //kmodule.xml 中定义的 ksession name
        KieSession kieSession = kieContainer.newKieSession("all-rules");
        Applicant applicant = new Applicant("Mr John Smith", 17);
        kieSession.insert(applicant);
        kieSession.fireAllRules();
        kieSession.dispose();
    }
}

public class Applicant {
    private String name;
    private int age;
    private boolean valid;

    public Applicant(String name, int age) {
        this.name = name;
        this.age = age;
        this.valid = true;
    }
    //getter/setter
}

public class Action {
    private String msg;

    public Action(String msg) {
        this.msg = msg;
    }

    public void doSomeThing() {
        System.out.println(msg);
    }
}
  • 运行结果
执行动作
不合法

规则动态更新

参考官方文档

  • 加载
import org.kie.api.KieServices;
import org.kie.api.builder.KieFileSystem;
import org.kie.api.builder.KieBuilder;

  KieServices ks = KieServices.Factory.get();
  KieFileSystem kfs = ks.newKieFileSystem()
  kfs.write("src/main/resources/KBase1/ruleSet1.drl", stringContainingAValidDRL)
  .write("src/main/resources/dtable.xls",
    kieServices.getResources().newInputStreamResource(dtableFileStream));

  KieBuilder kieBuilder = ks.newKieBuilder( kfs );
  // Enable executable model
  kieBuilder.buildAll(ExecutableModelProject.class)
  assertEquals(0, kieBuilder.getResults().getMessages(Message.Level.ERROR).size());
  • 更新
import org.kie.api.KieServices;
import org.kie.api.builder.ReleaseId;
import org.kie.api.runtime.KieContainer;
import org.kie.api.builder.KieScanner;

...

KieServices kieServices = KieServices.Factory.get();
ReleaseId releaseId = kieServices
  .newReleaseId("com.sample", "my-app", "1.0-SNAPSHOT");
KieContainer kContainer = kieServices.newKieContainer(releaseId);
KieScanner kScanner = kieServices.newKieScanner(kContainer);

// Start KIE scanner for polling the Maven repository every 10 seconds (10000 ms)
kScanner.start(10000L);

生产环境中使用Drools需要考虑的问题

  • 规则匹配完全依赖内存,Rete算法也使用空间换时间的方式提高效率,需要评估服务容量
  • 必须要实现规则动态更新
  • DSL对非开发同学,也不是很友好

你可能感兴趣的:(Drools入门)