2. 核心概念解析:规则、事实、动作、规则集、规则冲突与优先级
好,咱们正式开始聊规则引擎的核心概念。说实话,很多同学一开始就被这些术语搞晕了。什么规则、事实、动作……听着像哲学课。其实没那么复杂,我换个说法你就明白了。
规则引擎说白了,就是一个「如果…那么…」的机器。你给它一堆条件,它帮你判断,然后执行对应的操作。就这么简单。
2.1 规则(Rule)—— 引擎的灵魂
规则是规则引擎里最基本的单元。它长什么样?
// 伪代码示例
rule "检查交易金额"
when
$t: Transaction(amount > 10000)
then
$t.setRiskLevel("HIGH");
update($t);
end
你看,一个规则就两部分:条件(when) 和 结论(then)。条件就是「交易金额大于1万」,结论就是「标记为高风险」。
我个人习惯把规则写成自然语言能读懂的格式。为什么?因为业务人员也要看。你写一堆技术黑话,产品经理看不懂,最后还得你解释,累不累?
2.2 事实(Fact)—— 引擎的输入
事实就是你要判断的数据。可以是交易记录、用户信息、设备指纹……任何你想检查的东西。
举个例子:
// 事实对象
public class Transaction {
private String userId;
private BigDecimal amount;
private String ipAddress;
private String deviceId;
// getter/setter 省略
}
事实会被放到引擎的工作内存(Working Memory)里。规则引擎会拿着这些事实,一条一条去匹配规则的条件。
嗯,这里要注意:事实不是随便扔进去的。我见过有人把整个数据库表都塞进去,结果引擎跑得比蜗牛还慢。你想想看,事实越多,匹配的复杂度就越高。
2.3 动作(Action)—— 引擎的输出
动作就是规则匹配成功后要执行的操作。常见的动作有:
- 修改事实:比如把风险等级从低改成高
- 触发外部系统:调用风控接口、发送告警短信
- 记录日志:把匹配结果存到数据库
- 终止后续规则:一旦命中高风险,后面的规则就不用跑了
动作的设计有个原则:动作要轻量。别在动作里写复杂的业务逻辑,更别调远程接口。为什么?因为动作执行是同步的,你调个外部接口等3秒,整个引擎就卡住了。
2.4 规则集(RuleSet)—— 规则的容器
规则多了怎么办?总不能几百条规则堆在一起吧?这时候就需要规则集了。
规则集就是把相关规则打包在一起。比如:
| 规则集名称 | 包含规则 | 适用场景 |
|---|---|---|
| 登录风控 | 异地登录检测、设备指纹异常、密码错误次数 | 用户登录环节 |
| 交易风控 | 大额交易、频繁交易、黑名单商户 | 支付环节 |
| 反欺诈 | 团伙检测、虚假注册、薅羊毛识别 | 注册/活动环节 |
规则集的好处是:可以按需加载。登录场景只加载登录风控的规则集,交易场景只加载交易风控的。这样引擎的负担就小多了。
2.5 规则冲突与优先级—— 谁说了算?
这是最让人头疼的问题。两条规则同时匹配了,到底执行哪条?
举个例子:
规则A:如果交易金额 > 5000,则标记为"中风险"
规则B:如果交易金额 > 10000,则标记为"高风险"
一笔15000元的交易,两条规则都匹配了。按规则A,它是中风险;按规则B,它是高风险。到底听谁的?
这就引出了优先级的概念。
常见的冲突解决策略:
- 显式优先级:给每条规则一个数字,数字越小优先级越高。比如规则B优先级为1,规则A优先级为2,那就执行规则B。
- 最近优先:后加载的规则优先级更高。这个策略风险很大,我不推荐。
- 指定规则集优先级:整个规则集有一个优先级,里面的规则继承这个优先级。
2.6 知识体系总览
说了这么多,咱们用一张图来总结一下核心概念之间的关系:
从这张图可以看得很清楚:事实是输入,规则是判断逻辑,动作是输出。规则集把规则组织起来,优先级解决规则之间的冲突。整个流程就是:事实进来,引擎匹配规则,解决冲突,执行动作。
2.7 总结一下
这几个概念,说白了就是:
- 规则:if-then 的判断逻辑
- 事实:你要判断的数据
- 动作:判断完了要干嘛
- 规则集:把规则分门别类放好
- 冲突与优先级:多条规则都匹配时,听谁的
嗯,这些概念看着简单,但实际项目中踩坑的人真不少。我见过最离谱的,是把规则写成了存储过程,每次改规则都要重启数据库。你说这得多折腾?
所以,把基础概念吃透,后面设计规则引擎的时候才能游刃有余。下一节咱们聊聊规则引擎的架构设计,那才是真正考验功底的地方。
公众号:蓝海资料掘金营,微信deep3321