2

Drools规则引擎实战

 8 months ago
source link: https://www.51cto.com/article/770009.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Drools规则引擎实战

作者:余贤雷 卢阳 2023-10-16 17:41:40
在机顶盒软探针项目中,项目需要针对地域维度对机顶盒指标:播放成功率、收视用户数、EPG请求成功率,实现准实时的告警判定。针对告警规则的多变性,我们引入了规则引擎作为告警规则的实现方式。
e9aeb5322607a499bb5057152cfa564571f448.jpg

Part 1 规则引擎

规则引擎:全称为业务规则管理系统,英文名为BRMS。规则引擎的主要思想是将应用程序中的业务决策部分分离出来,并使用预定义的语义模块编写业务决策(业务规则),由用户或 开发者在需要时进行配置、管理。需要注意的是规则引擎并不是一个具体的技术框架,而是指的一类系统,即业务规则管理系统。

java开源的规则引擎有:Drools、Easy Rules、Mandarax、IBM ILOG。使用最为广泛并且开源的是Drools

主要应用场景:对于一些存在比较复杂的业务规则并且业务规则会频繁变换的系统比较适合使用规则引擎,如下:

风控决策系统-------风险贷款、风险评估

反欺诈项目-----银行贷款、征信验证、反洗钱

实时反欺诈平台-----手机支付、信用卡消费

Drools规则引擎构成

drools规则引擎由以下几部分构成:

  • Working Memory(工作内存)
  • Rules(规则库)
  • Inference Engine(推理引擎)

◆Pattern Match(匹配器)具体匹配那一个规则,由它来完成

◆Agenda(议程)

◆Execution Engine(执行引擎)

Drools规则引擎概念

Working Memory:工作内存,drools规则引擎会从Working Memory中获取数据并和规则文件中定义的规则进行模式匹配,所以我们开发的应用程序只需要将我们的数据插入到Working Memory中即可,例如本案例中我们调用kieSession.insert(order)就是将order对象插入到了工作内存中。

Fact:事实,是指在drools 规则应用当中,将一个普通的JavaBean插入到Working Memory后的对象就是Fact对象,例如本案例中的Order对象就属于Fact对象。Fact对象是我们的应用和规则引擎进行数据交互的桥梁或通道。

Rules:规则库,我们在规则文件中定义的规则都会被加载到规则库中。

Pattern Matcher:匹配器,将Rule Base中的所有规则与Working Memory中的Fact对象进行模式匹配,匹配成功的规则将被激活并放入Agenda中。

Agenda:议程,用于存放通过匹配器进行模式匹配后被激活的规则。

Drools 基础语法

规则文件构成

package 包名

只限于逻辑上的管理,同一个包名下的查询或者函数可以直接调用

import

用于导入类或者静态方法

global

function

自定义函数

query

rule end

一个规则通常包含三个部分:属性部分(attribute)、条件部分(LHS)和结果部分(RHS)

语法结构体:

rule "ruleName"
    attributes
    when
        LHS
    then
        RHS
end

rule:关键字,表示规则开始,参数为规则的唯一名称。

attributes:规则属性,是rule与when之间的参数,为可选项。

when:关键字,后面跟规则的条件部分。

LHS(Left Hand Side):是规则的条件部分的通用名称。它由零个或多个条件元素组成。如果LHS为空,则它将被视为始终为true的条件元素。

then:关键字,后面跟规则的结果部分。

RHS(Right Hand Side):是规则的后果或行动部分的通用名称。

end:关键字,表示一个规则结束。

Part 2 规则比较操作符

符号

说明

>=

<=

contains

检查一个Fact对象的某个属性值是否包含一个指定的对象值

not contains

检查一个Fact对象的某个属性值是否不包含一个指定的对象值

memberOf

判断一个Fact对象的某个属性是否在一个或多个集合中

not memberOf

判断一个Fact对象的某个属性是否不在一个或多个集合中

matches

判断一个Fact对象的属性是否与提供的标准的Java正则表达式进行匹配

not matches

判断一个Fact对象的属性是否不与提供的标准的Java正则表达式进行匹配

Part 3 Drools 规则属性 attributes

Drools中提供的属性如下表(部分属性)

属性名

说明

salience

指定规则执行优先级

dialect

指定规则使用的语言类型,取值为java和mvel

enabled

指定规则是否启用

date-effective

指定规则生效时间

date-expires

指定规则失效时间

activation-group

激活分组,具有相同分组名称的规则只能有一个规则触发

agenda-group

议程分组,只有获取焦点的组中的规则才有可能触发

timer

定时器,指定规则触发的时间

auto-focus

自动获取焦点,一般结合agenda-group一起使用

no-loop

防止死循环,防止自己更新规则再次触发

lock-on-active

no-loop增强版本。可防止别人更新规则再次出发

Part 4 项目应用

省机顶盒软探针平台为实现机顶盒用户视频使用质量的实时监控,采用实时大数据进行准实时的指标统计,指标结果推送kafka,由平台新增的告警引擎实时消费kafka数据并通过预定制的专家规则实现实时的告警判定,最终告警结果实时通知反馈到告警平台,实现告警到告警恢复的生命周期。

图片

Part 5 规则示例

rule "播放成功率告警"
no-loop true
when
    $fact:Fact()
    eval($fact.getPlay() > 0.0)
    eval($fact.getPlay() < MapUtils.getDoubleValue($fact, "playThreshold", 0.96))
then
    RuleResult fr = new RuleResult("播放成功率告警");
    fr.setRuleCode(900001);
    fr.setActualTime(MapUtils.getString($fact, "actualTime"));
    fr.setAlarmTime(RuleUtil.getAlarmTime(MapUtils.getString($fact, "actualTime"), MapUtils.getString($fact, "900001")));
    //说明当前是要告警的
    fr.setAlarmStatus("1");
    fr.setAlarmTitle("指标播放成功率异常");
    fr.setLocateInfo("指标播放成功率异常");
    fr.setAlarmText(RuleUtil.playAlarmText($fact, MapUtils.getDoubleValue($fact, "playThreshold", 0.96)));
    insert(fr);
end




rule "播放成功率告警结束"
no-loop true
when
    $fact:Fact()
    eval($fact.getPlay() >= MapUtils.getDoubleValue($fact, "playThreshold", 0.96))
    eval(MapUtils.getLongValue($fact, "900001") > 0)
    eval(RuleUtil.checkAlarmTime($fact.getActualTime(), MapUtils.getLongValue($fact, "900001_time"), MapUtils.getLongValue($fact, "reThreshold", 900000)))
then
    RuleResult fr = new RuleResult("播放成功率告警恢复");
    fr.setRuleCode(900001);
    fr.setActualTime(MapUtils.getString($fact, "actualTime"));
    fr.setAlarmTime(MapUtils.getString($fact, "900001"));
    fr.setAlarmStatus("0");
    fr.setMsg("告警恢复");
    fr.setAlarmTitle("指标播放成功率异常");
    fr.setLocateInfo("指标播放成功率异常");
logger.info("播放告警恢复了{}", $fact);
insert(fr);
责任编辑:庞桂玉 来源: 移动Labs

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK