2. 基础知识

在进入规则引擎的工程实现之前,先把“黑白名单”和“动态名单”这套语言体系讲清楚。很多团队在项目初期把黑白名单当成简单的“查表判断”,结果一旦业务要求“临时封禁 30 分钟”“同一设备 5 分钟内失败 3 次就拉黑”“VIP 用户永远放行”时,代码迅速退化成大量 if-else,维护成本急剧上升。本章的目标是建立一套统一的概念模型,让你在后续设计规则引擎时,能够准确地把业务语言翻译成可执行的规则结构。

一、核心概念:名单、规则与决策

黑白名单本质上是一种基于集合的准入控制。白名单表示“默认拒绝,仅允许集合内对象通过”,黑名单表示“默认允许,仅拒绝集合内对象通过”。两者不是简单的“好名单/坏名单”,而是两种相反的默认策略。理解这一点非常关键:当业务说“加白”时,通常意味着该对象在原本被拦截的场景下获得放行;当业务说“加黑”时,意味着该对象在原本被允许的场景下被拒绝。

动态名单规则引擎则是在静态名单之上,引入条件、时间、计数和优先级。它不再只回答“这个对象在不在名单里”,而是回答“在当前上下文下,根据一组规则,这个对象应该被允许、拒绝还是挑战”。因此,规则引擎的核心输出不是布尔值,而是一个决策结果,通常包括:决策动作(allow/deny/challenge/review)、命中规则、生效时长、置信度和可解释原因。

核心原理:名单是数据,规则是逻辑,引擎是执行器。静态名单解决“是谁”,动态规则解决“在什么条件下、多久、因为什么”。

二、常见术语与数据模型

为了让后续章节的代码和配置有共同语言,这里集中定义一批高频术语。建议在团队内部统一命名,避免“黑名单”“封禁列表”“拒绝列表”混用导致沟通歧义。

术语含义典型示例
主体(Subject)被判断的对象用户ID、IP、设备指纹、手机号
名单项(Entry)名单中的一条记录IP 192.168.1.10 加入黑名单
规则(Rule)条件与动作的组合5分钟内失败3次 → 封禁30分钟
条件(Condition)触发规则所需的判断失败次数 >= 3 且 来源=登录
动作(Action)命中后的处置deny、allow、challenge、review
优先级(Priority)多规则冲突时的顺序白名单优先于黑名单
TTL名单项或规则的存活时间封禁 1800 秒后自动失效
命中(Hit)规则条件被满足规则 R-102 命中
决策(Decision)引擎最终输出deny,原因:R-102

其中,优先级和TTL是动态名单区别于静态名单的两个关键字段。没有优先级,规则冲突时结果不可预测;没有 TTL,临时封禁会变成永久封禁,运营人员不得不手动清理。

三、方法流程:一次决策是如何产生的

一个可落地的动态名单规则引擎,通常遵循以下流程。你可以把它理解为“从请求到决策”的标准管道:

  1. 上下文采集:收集主体标识、时间、来源、行为计数等上下文。
  2. 名单查询:先查静态白名单和黑名单,得到基础判断。
  3. 规则匹配:按优先级遍历动态规则,判断条件是否满足。
  4. 冲突消解:当多条规则命中时,按优先级、特异性或显式策略决定胜出规则。
  5. 决策输出:返回动作、原因、TTL 和建议的处置方式。
  6. 审计与回流:记录命中日志,供复盘和规则调优。

下面是一段简化的规则配置示例,展示了静态名单与动态规则如何共存。注意 priority 越小优先级越高,ttl 单位为秒。

{
  "whitelist": [
    { "subject": "user:10086", "reason": "VIP", "ttl": 0 }
  ],
  "blacklist": [
    { "subject": "ip:203.0.113.7", "reason": "恶意扫描", "ttl": 86400 }
  ],
  "rules": [
    {
      "id": "R-102",
      "priority": 10,
      "condition": "login_fail_count >= 3 within 300s",
      "action": "deny",
      "ttl": 1800,
      "reason": "登录失败次数过多"
    },
    {
      "id": "R-201",
      "priority": 20,
      "condition": "device_risk_score > 80",
      "action": "challenge",
      "ttl": 600,
      "reason": "设备风险高"
    }
  ]
}

当请求到来时,引擎先检查白名单,若命中则直接放行;否则检查黑名单,命中则拒绝;否则进入动态规则匹配。这种“静态优先、动态补充”的顺序,可以避免动态规则误伤已确认的可信对象。

四、应用场景与常见误区

黑白名单与动态规则引擎的应用非常广泛,常见场景包括:

  • 账号安全:登录失败多次临时封禁、异地登录挑战、VIP 白名单放行。
  • 风控反欺诈:设备指纹黑名单、IP 黑名单、行为序列动态评分。
  • API 网关:按调用方 AppKey 做白名单,按异常流量做动态限流封禁。
  • 内容审核:作者白名单优先发布,违规账号动态降权或禁言。
  • 运维封禁:临时封禁异常爬虫 IP,TTL 到期自动解封。

实践建议:优先使用“白名单 + 动态规则”组合,而不是维护一个巨大的黑名单。黑名单天然滞后,动态规则可以基于行为实时收敛。

在实际落地中,有几个高频误区值得警惕。第一,把白名单当成万能钥匙:白名单对象一旦被盗用,攻击者将获得完全信任,因此白名单也应结合上下文校验。第二,忽略优先级设计:多条规则同时命中时,如果没有明确的优先级,结果会随遍历顺序变化,难以复现。第三,TTL 缺失或过长:临时封禁变成永久封禁,运营成本高。第四,规则不可解释:只返回 deny 而不返回命中规则和原因,排查问题时只能靠猜。

复盘提醒:任何一次误封或漏放,都应能回答三个问题——命中了哪条规则?当时的上下文是什么?TTL 是否合理?如果回答不了,说明引擎的可观测性不足,需要优先补齐日志与审计。