3. 规则语言入门:DRL(Drools Rule Language)语法基础
DRL(Drools Rule Language)是 Drools 规则引擎的原生规则语言,也是规则冲突检测与特征服务联动中最核心的编写载体。一个完整的 DRL 规则由三个部分组成:规则头(Rule Header)、条件部分(LHS,Left-Hand Side) 和 动作部分(RHS,Right-Hand Side)。理解这三者的结构、约束与协作方式,是后续进行规则冲突分析、特征编排和性能调优的前提。
3.1 规则头(Rule Header)
规则头定义了规则的元信息,包括规则名称、属性、优先级和分组等。它是规则引擎识别和执行规则的入口。
| 关键字 | 说明 | 示例 |
|---|---|---|
rule |
声明规则开始,后跟规则名称 | rule "检测高风险交易" |
salience |
设置规则优先级,数值越大越先执行 | salience 100 |
no-loop |
防止规则自身修改 Fact 导致无限循环 | no-loop true |
activation-group |
同一组内只激活一条规则(互斥) | activation-group "risk-level" |
agenda-group |
将规则分组到议程,控制执行焦点 | agenda-group "feature-eval" |
when |
标记条件部分开始 | when |
then |
标记动作部分开始 | then |
end |
标记规则结束 | end |
实践建议:在特征服务联动场景中,
salience 和 activation-group 是控制规则冲突与特征计算顺序的关键属性。建议为每个规则显式设置 no-loop true,避免因特征值更新导致规则重复触发。
3.2 条件部分(LHS)
LHS 是规则的条件匹配区域,使用 when 关键字引导。引擎会在此处对工作内存中的 Fact 对象进行模式匹配。LHS 支持多种约束语法,包括字段比较、逻辑组合、存在性检查等。
3.2.1 基本模式与字段约束
rule "检查交易金额超限"
when
$t : Transaction( amount > 10000, currency == "CNY" )
then
// RHS 动作
end
上述规则中:
$t是绑定变量,可在 RHS 中引用该 Fact 对象。Transaction是 Fact 类型。amount > 10000和currency == "CNY"是字段约束,支持>、<、==、!=、matches、contains等操作符。
3.2.2 多条件组合与逻辑操作符
rule "组合条件:高风险设备 + 异常时段"
when
$d : Device( riskScore >= 80 )
$t : Transaction( deviceId == $d.id, hourOfDay < 6 || hourOfDay > 23 )
then
// 触发联动动作
end
LHS 支持 &&(与)、||(或)、!(非)以及括号分组。多个 Fact 模式之间默认是 && 关系,所有模式必须同时匹配。
3.2.3 存在性与集合约束
| 关键字 | 用途 | 示例 |
|---|---|---|
exists |
检查是否存在至少一个匹配 | exists Alert( severity == "HIGH" ) |
not |
检查不存在任何匹配 | not Blacklist( ip == $t.clientIp ) |
forall |
检查所有对象都满足条件 | forall( Feature( status == "READY" ) ) |
collect |
收集匹配对象到集合 | List from collect( Feature( name.startsWith("risk_") ) ) |
常见陷阱:
exists 和 not 在规则冲突检测中容易导致意外的激活/失活。例如,not Blacklist(...) 会在黑名单 Fact 被插入或删除时重新评估,可能引发连锁冲突。建议在关键规则上使用 activation-group 进行隔离。
3.3 动作部分(RHS)
RHS 是规则触发后执行的动作区域,使用 then 关键字引导。RHS 中可以编写 Java 代码、调用服务、更新 Fact、插入新 Fact 或触发其他规则。
3.3.1 常用 RHS 操作
rule "特征联动:更新风险评分"
when
$t : Transaction( amount > 50000 )
$f : Feature( transactionId == $t.id, name == "risk_score" )
then
// 更新特征值
modify( $f ) {
setValue( $f.getValue() + 20 ),
setUpdatedTime( new java.util.Date() )
}
// 插入告警 Fact
Alert alert = new Alert();
alert.setType("HIGH_RISK");
alert.setMessage("大额交易风险提升");
insert( alert );
// 调用外部特征服务
FeatureServiceClient.updateFeature($t.getId(), "risk_level", "HIGH");
end
3.3.2 RHS 中的关键方法与宏
| 方法/宏 | 作用 | 冲突影响 |
|---|---|---|
modify( $fact ) { ... } |
更新 Fact 属性并通知引擎 | 可能重新激活其他规则 |
update( $fact ) |
更新 Fact 并重新评估 | 高冲突风险,慎用 |
insert( newFact ) |
插入新 Fact 到工作内存 | 可能触发新规则链 |
retract( $fact ) |
从工作内存移除 Fact | 可能导致规则失活 |
drools.halt() |
立即停止规则执行 | 中断当前议程 |
特征服务联动要点:在 RHS 中调用外部特征服务时,建议使用异步回调或批量更新接口,避免在规则执行线程中阻塞。同时,
modify 操作会触发规则引擎的重新评估,务必配合 no-loop 和 activation-group 防止冲突风暴。
3.4 DRL 规则结构总览
以下 SVG 图展示了 DRL 规则的完整结构,以及规则头、LHS、RHS 之间的数据流与执行关系。
3.5 完整 DRL 规则示例
以下是一个结合特征服务联动的完整 DRL 规则,展示了规则头、LHS 和 RHS 的协同工作:
package com.risk.feature.rules
import com.risk.model.Transaction
import com.risk.model.Feature
import com.risk.model.Alert
import com.risk.service.FeatureServiceClient
rule "特征联动:设备指纹异常检测"
salience 200
no-loop true
activation-group "device-risk"
when
// 条件1:交易金额超过阈值
$t : Transaction( amount > 20000, status == "PENDING" )
// 条件2:设备指纹特征异常(风险分 > 70 或 新设备标记)
$f : Feature( transactionId == $t.id,
(name == "device_risk_score" && doubleValue > 70) ||
(name == "is_new_device" && stringValue == "true") )
// 条件3:该设备在过去1小时内没有触发过同类告警(防重复)
not Alert( deviceId == $t.deviceId, type == "DEVICE_ANOMALY",
timestamp > ($t.timestamp - 3600000) )
then
// 动作1:更新特征值
modify( $f ) {
setDoubleValue( $f.getDoubleValue() + 15 ),
setUpdatedTime( new java.util.Date() )
}
// 动作2:插入告警
Alert alert = new Alert();
alert.setType("DEVICE_ANOMALY");
alert.setDeviceId($t.getDeviceId());
alert.setTransactionId($t.getId());
alert.setTimestamp(new java.util.Date());
insert( alert );
// 动作3:调用外部特征服务,同步更新特征库
FeatureServiceClient.updateFeature(
$t.getId(),
"device_anomaly_flag",
"true"
);
// 动作4:日志记录(生产环境建议使用 Logger)
System.out.println("设备异常检测触发: " + $t.getId());
end
学习路径提示:掌握 DRL 语法后,下一步应重点理解规则冲突的触发机制——特别是
modify 和 insert 如何导致 LHS 重新评估。这是第 4 章“规则冲突检测原理”的核心内容。