4. 规则表达与语法:规则的基本结构、条件表达式、动作定义、规则优先级

好,咱们今天聊聊规则引擎里最核心的东西——规则怎么写。

说实话,我见过不少团队,规则引擎选型搞定了,部署也跑通了,结果卡在规则定义上。为什么?因为规则写得不清晰,维护起来像在解谜。今天我就把我在生产环境里踩过的坑、总结的经验,一次性讲清楚。

4.1 规则的基本结构

一条规则,说白了就是「如果……那么……」的逻辑。但在工程实现上,我们需要把它拆成几个固定的部分。

我个人习惯把规则结构分为三块:

  • 规则头:规则的元信息,比如规则ID、名称、版本、状态
  • 条件体:触发规则的条件表达式
  • 动作体:条件满足时要执行的操作

举个例子,一个简单的风控规则长这样:

规则ID: R001
名称: 高频交易拦截
优先级: 10
条件: 交易金额 > 10000 AND 交易频率 > 5次/分钟
动作: 拒绝交易,记录告警日志

嗯,这里要注意,规则头里的优先级不是随便填的。我在项目中遇到过,有人把所有规则优先级都设成1,结果规则引擎执行时完全乱套了。优先级决定了规则执行的先后顺序,后面我会详细讲。

4.2 条件表达式

条件表达式是规则引擎的「大脑」。它决定了规则什么时候被触发。

常见的条件表达式类型有:

  • 比较表达式:金额 > 1000,次数 >= 5
  • 逻辑表达式:AND、OR、NOT 组合
  • 集合表达式:IN、NOT IN、CONTAINS
  • 时间表达式:时间范围、时间间隔判断

你想想看,如果条件表达式写得太复杂,后期维护就是噩梦。我曾经接手过一个项目,一条规则的条件写了200多行,嵌套了七八层AND和OR。后来出问题了,没人敢改,因为一改就崩。

核心原则:条件表达式要「原子化」。每个条件只判断一件事,然后用逻辑运算符组合。

来看一个实际的风控规则条件:

// 条件:同一IP在5分钟内登录失败超过3次
条件表达式:
  login_fail_count >= 3 
  AND time_diff(last_fail_time, now) <= 300 
  AND same_ip == true

这样写,每个条件都很清晰,出了问题也能快速定位。

4.3 动作定义

条件满足了,然后呢?动作定义就是回答这个问题的。

动作可以分为几类:

动作类型 说明 示例
阻断动作 直接拒绝请求 拒绝交易、封禁账号
告警动作 通知相关人员 发送短信、邮件告警
标记动作 给数据打标签 标记为高风险用户
记录动作 写入日志或数据库 记录审计日志
升级动作 触发二次验证 要求短信验证、人工审核

动作定义时,我建议遵循「最小权限原则」。什么意思?就是动作只做它该做的事,不要在一个动作里既拒绝交易又发短信又改数据库又调外部接口。动作越纯粹,越容易测试和维护。

小技巧:动作可以组合使用。比如先记录日志,再拒绝交易,最后发送告警。但要注意执行顺序,别先拒绝了再记录日志,那就记录不到了。

4.4 规则优先级

优先级这东西,看着简单,用起来全是坑。

规则优先级决定了:

  • 多条规则同时满足时,先执行哪条
  • 高优先级规则的结果是否可以覆盖低优先级规则的结果
  • 规则引擎的终止策略(遇到高优先级规则是否继续执行)

我一般把优先级分为几个等级:

优先级范围 用途 示例
1-10 系统级规则(最高) 黑名单拦截、法律合规规则
11-50 业务级规则 风控策略、交易限额规则
51-100 辅助级规则 数据标记、统计规则

数字越小,优先级越高。我曾经见过有人把优先级设成负数,结果规则引擎直接报错。所以,一定要在规则引擎设计时就约定好优先级范围,别让开发人员随意填。

避坑指南:我曾经在一个项目中,两条规则优先级相同,结果规则引擎随机执行其中一条,导致同样的请求有时被拦截有时放行。排查了整整两天才发现是优先级冲突。所以,优先级一定要唯一,或者至少要有明确的冲突处理策略。

4.5 知识体系总览

说了这么多,咱们用一张图把规则表达与语法的核心逻辑串起来:

规则表达与语法核心结构 一条完整的规则 规则头 规则ID、名称 版本、状态、优先级 条件体 比较、逻辑、集合 时间表达式 动作体 阻断、告警、标记 记录、升级 条件表达式类型 比较 | 逻辑 | 集合 时间 | 正则 动作执行策略 顺序执行 | 并行执行 组合动作 | 条件动作 规则优先级 1-10 系统级 11-50 业务级 | 51-100 辅助级 规则 = 规则头 + 条件体 + 动作体 + 优先级 清晰的结构 + 原子化的条件 + 纯粹的动作 + 合理的优先级 = 可维护的规则

这张图把规则表达的核心要素都串起来了。你写规则的时候,就按这个结构来,基本不会出大问题。

4.6 实战建议

最后,给几个实战中的建议:

  • 规则版本管理:每条规则都要有版本号,方便回滚和追溯
  • 规则测试:上线前一定要有测试用例覆盖,特别是边界条件
  • 规则监控:监控规则的命中率、执行耗时,及时发现异常
  • 规则文档:每条规则都要有清晰的业务说明,别让后人猜

我的习惯:我会在规则引擎里加一个「规则注释」字段,专门用来写业务背景。比如「这条规则是为了应对2023年双十一的刷单行为,预计12月31日下线」。这样半年后回头看,还能知道当初为什么这么写。

好了,规则表达与语法就讲到这里。记住,规则写得好不好,直接决定了风控系统的成败。别图一时省事,把规则写得乱七八糟。后面维护的时候,你会感谢现在认真写规则的自己。


公众号:蓝海资料掘金营,微信deep3321