3. 规则优先级入门
在规则引擎、访问控制、风控系统、推荐策略以及各类业务决策系统中,规则往往不是孤立存在的。同一个事实可能同时命中多条规则,而这些规则给出的结论却可能不同:有的允许,有的拒绝;有的给出折扣,有的给出原价;有的触发告警,有的仅记录日志。此时,系统必须回答一个核心问题:当多条规则同时生效时,究竟听谁的?这就是规则优先级要解决的问题。
一、什么是规则优先级
规则优先级(Rule Priority)是附加在规则上的一种排序或权重信息,用于在规则冲突或竞争时决定哪条规则先被采用、哪条规则后被执行、哪条规则被覆盖。它本质上是一种决策仲裁机制,把“多条规则都匹配”这一不确定状态,转化为“按既定顺序处理”的确定状态。
需要区分三个容易混淆的概念:
- 匹配(Match):规则条件是否被当前事实满足,回答“是否命中”。
- 优先级(Priority):多条规则命中后谁先谁后,回答“先处理谁”。
- 互斥(Exclusion):规则之间是否不能同时生效,回答“能否共存”。
优先级不改变规则本身的匹配逻辑,它只改变规则被选择、执行或合并时的顺序。因此,优先级是规则治理中最基础、也最容易被低估的一环。
二、优先级的作用
优先级在规则系统中主要承担四类作用:
- 冲突消解:当两条规则结论相反时,高优先级规则胜出。例如“VIP 用户免运费”应覆盖“普通用户满 99 免运费”。
- 执行排序:在链式规则中,先执行哪条规则会影响后续事实。例如先做黑名单拦截,再做额度计算,避免无效计算。
- 策略分层:把通用规则、行业规则、客户定制规则分层,定制层优先级高于通用层,实现“默认 + 覆盖”的配置模式。
- 灰度与兜底:高优先级规则用于紧急开关或灰度策略,低优先级规则作为默认兜底,保证系统始终有结论。
三、常见表示方式:数字、层级与标签
不同系统对优先级的表达方式不同,常见有三类:数字型、层级型和标签型。它们各有适用场景,也常被组合使用。
| 表示方式 | 典型形式 | 优点 | 风险 | 适用场景 |
|---|---|---|---|---|
| 数字型 | 0、10、100、1000;或 -1、0、1 | 排序精确,易于比较和插入 | 数值膨胀、间距耗尽、含义不直观 | 规则数量多、需要精细排序的引擎 |
| 层级型 | BLOCKER > HIGH > MEDIUM > LOW | 语义清晰,便于团队沟通 | 同层内仍需二次排序 | 策略分层、审批流、告警分级 |
| 标签型 | override、default、fallback、emergency | 表达意图,贴近业务语言 | 需要映射为可计算顺序 | 配置化平台、低代码规则编排 |
数字型最常见,因为它可以直接比较。例如很多规则引擎使用 salience 字段,数值越大越先执行。层级型适合人读,标签型适合业务配置。工程实践中,通常做法是:对外暴露层级或标签,对内映射为数字,兼顾可读性与可计算性。
四、简单示例:从配置到执行
假设一个电商促销系统有三条规则:
规则A:VIP用户,享受9折,priority = 100
规则B:满200减30,priority = 50
规则C:默认包邮,priority = 10
当一位 VIP 用户订单金额为 260 元时,三条规则都可能命中。若系统按优先级从高到低执行,则先应用 VIP 9折,再判断是否满足满减,最后应用默认包邮。若优先级配置反了,例如默认包邮优先级最高,则可能出现“先包邮、后打折”的顺序错乱,导致运费计算错误。
再看一个访问控制场景,用层级型表示:
priority: BLOCKER -> 拒绝所有来自黑名单IP的请求
priority: HIGH -> 拒绝未认证用户访问敏感接口
priority: MEDIUM -> 限制单用户每分钟100次调用
priority: LOW -> 记录访问日志
当黑名单 IP 同时触发限流和日志规则时,BLOCKER 层先执行并直接拒绝,后续规则不再产生业务影响。这就是优先级带来的短路效应:高优先级规则可以终止或覆盖低优先级规则的处理路径。
五、误区与复盘
优先级入门阶段最常见的误区有四个:
- 把优先级当业务重要性:优先级高只代表先执行,不代表业务价值高。日志规则优先级低,但绝不能删除。
- 数字间距过小:初始用 1、2、3,后续插入只能改成 1.5、1.25,最终难以维护。建议初始间距设为 100 或 1000。
- 忽略同优先级行为:多条规则优先级相同时,系统可能按加载顺序、随机顺序或未定义顺序执行,导致结果不稳定。必须明确同优先级策略。
- 优先级与互斥混用:优先级解决“谁先”,互斥解决“能否同时”。用优先级去模拟互斥,往往会在规则增多后失效。
复盘一个真实场景:某风控系统上线初期,所有规则优先级都设为 0,依赖数据库返回顺序执行。结果同一用户在不同时间得到不同结论,因为数据库索引变化改变了返回顺序。后来团队引入层级优先级,并规定同层按规则 ID 升序执行,问题才彻底解决。这个案例说明:优先级不仅是排序工具,更是系统确定性的来源。
掌握优先级的定义、作用与表示方式,是后续学习互斥检测和依赖检测的前提。只有先明确“谁先谁后”,才能进一步讨论“谁和谁不能同时存在”以及“谁依赖谁”。