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依赖
  <properties>
    <drools.version>7.5.0.Final</drools.version>
  </properties>
  <dependencies>
    <dependency>
      <groupId>org.kie</groupId>
      <artifactId>kie-api</artifactId>
      <version>${drools.version}</version>
    </dependency>
    <dependency>
      <groupId>org.drools</groupId>
      <artifactId>drools-compiler</artifactId>
      <version>${drools.version}</version>
    </dependency>
    <dependency>
      <groupId>org.drools</groupId>
      <artifactId>drools-core</artifactId>
      <version>${drools.version}</version>
    </dependency>   
  </dependencies>
  • 目录要求
idea目录
  • kmodule.xml
<?xml version="1.0" encoding="utf-8" ?>
<kmodule xmlns="http://www.drools.org/xsd/kmodule">
    <kbase name="rules">
        <ksession name="all-rules"></ksession>
    </kbase>
</kmodule>
  • 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对非开发同学,也不是很友好
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,752评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,100评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,244评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,099评论 1 286
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,210评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,307评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,346评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,133评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,546评论 1 306
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,849评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,019评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,702评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,331评论 3 319
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,030评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,260评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,871评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,898评论 2 351

推荐阅读更多精彩内容