第二章:规则引擎的前世今生

从硬编码到Drools,再到现代轻量级引擎,聊聊我经历过的那些「坑」。

做风控这些年,我见过太多团队在规则引擎上栽跟头。有人觉得这东西高大上,非要上Drools;有人觉得不就是if-else嘛,自己写一套得了。结果呢?要么系统臃肿得像头大象,要么改个规则要发版三天。

今天我就跟你聊聊,规则引擎这二十多年是怎么演变的。我踩过的坑,你大概率也会遇到。

1. 硬编码时代:最原始,也最痛苦

2000年初,我刚入行那会儿。风控规则怎么写?直接写在Java代码里。

if (amount > 10000 && riskLevel.equals("HIGH")) {
    return "REJECT";
} else if (userAge < 18) {
    return "MANUAL_REVIEW";
} else {
    return "APPROVE";
}

看着简单吧?但实际项目里,这种if-else能堆上千行。我接手过一个老系统,一个方法里嵌套了8层if-else,改一个条件要翻半天代码。

我曾经踩过的坑:有一次上线前,业务说“把风控阈值从5000改成8000”。我改了代码,测试通过,上线。结果第二天发现,有个分支逻辑没覆盖到,误放过了一笔欺诈交易。嗯,从那以后,我发誓再也不在代码里硬编码规则。

硬编码的问题很明显:

  • 改规则 = 改代码 = 发版,周期至少一天
  • 业务人员没法自己改,全得靠开发
  • 代码可读性差,维护成本高
  • 没有版本管理,回滚全靠git

说白了,硬编码适合规则极少、几乎不变的系统。但凡规则超过20条,你就该考虑换方案了。

3. 规则引擎的黄金时代:Drools

2005年左右,Drools开始流行。它引入了Rete算法,把规则和代码彻底分离。

你写规则是这样的:

rule "高风险交易拦截"
    when
        $t: Transaction(amount > 10000, riskLevel == "HIGH")
    then
        $t.setResult("REJECT");
        update($t);
end

看着挺优雅,对吧?但实际用起来,坑也不少。

Drools的优点:
  • 规则和代码分离,业务人员可以写规则
  • 支持复杂的推理逻辑(前向链、后向链)
  • 有专门的规则编辑器(Drools Workbench)
  • 性能不错,Rete算法优化了匹配效率

但我要说点实话。Drools在中小型项目里,其实有点「杀鸡用牛刀」。

我曾经踩过的坑:2015年,我给一个支付公司做风控系统。上了Drools,规则写了300多条。结果呢?每次规则变更,Drools的规则编译要30秒。业务人员改个阈值,等编译等得想骂人。后来我查了下,Drools的规则引擎启动时会把所有规则编译成Drools的AST,规则多了确实慢。

Drools适合什么场景?

  • 规则数量在100-500条之间
  • 规则逻辑复杂,需要推理(比如保险核保、医疗诊断)
  • 团队有专门的规则工程师

但如果你只是做简单的风控拦截(金额>阈值、黑名单匹配),Drools就太重了。

4. 现代轻量级引擎:简单、高效、可嵌入

2018年以后,微服务架构火了。大家发现,Drools这种重量级引擎在微服务里很难用。启动慢、内存占用高、部署复杂。

于是,轻量级规则引擎开始崛起。比如:

  • EasyRules:Java写的,几百KB,支持注解和表达式
  • Nools:Node.js的规则引擎,适合前端风控
  • JSON Rules Engine:规则写成JSON,解析执行
  • 自研表达式引擎:基于MVEL、Aviator、QLExpress

我现在的项目,用的是自研的轻量级引擎。规则长这样:

{
  "rules": [
    {
      "name": "高风险交易拦截",
      "condition": "amount > 10000 && riskLevel == 'HIGH'",
      "action": "return 'REJECT'"
    },
    {
      "name": "未成年人工审核",
      "condition": "userAge < 18",
      "action": "return 'MANUAL_REVIEW'"
    }
  ]
}

规则存在数据库或配置中心,改规则不用重启服务。性能呢?单机每秒能处理5万次规则匹配。

我的建议:如果你的规则不超过200条,逻辑不涉及推理,直接用表达式引擎+配置中心就够了。别为了「高大上」硬上Drools,那是给自己挖坑。

5. 一张图看懂规则引擎的演进

下面这张图,是我自己画的。它展示了规则引擎从硬编码到轻量级的演进路径,以及每个阶段的典型代表。

规则引擎演进路线图 1 硬编码 2000-2005 if-else写在代码里 2 Drools 2005-2015 Rete算法,规则与代码分离 3 轻量级引擎 2018-至今 JSON规则,表达式引擎 4 AI+规则 未来趋势 规则+模型混合决策 各阶段对比 维度 硬编码 Drools 轻量级引擎 启动速度 慢(30s+) 极快(ms级) 规则变更 改代码发版 热加载 实时生效 内存占用 高(500MB+) 低(几十MB) 业务人员参与 不可能 需要培训 可以 适用场景 规则极少 复杂推理 风控拦截

6. 我踩过的那些坑,总结一下

这些年,我见过太多团队在规则引擎上走弯路。我总结了几条血泪教训:

  1. 别为了用引擎而用引擎。如果你的规则不超过10条,硬编码反而更简单。别觉得用Drools显得「专业」。
  2. 规则引擎不是银弹。它解决的是「规则频繁变更」的问题,不是「性能问题」。如果规则逻辑复杂到需要推理,Drools合适;如果只是简单判断,轻量级引擎更香。
  3. 注意规则的可测试性。我见过一个项目,规则引擎上线后,业务人员改了规则,没有测试,直接上线。结果呢?误杀了一堆正常交易。规则引擎一定要有沙箱环境,改规则先测试再上线。
  4. 性能监控不能少。规则引擎跑得慢,往往是规则写得烂。比如循环引用、递归调用。一定要加监控,看每条规则的执行耗时。
  5. 版本管理要做好。规则也是代码,也要有版本。我见过一个团队,规则存在数据库里,没有版本号。出问题了,回滚都不知道回滚到哪个版本。
我的建议:如果你现在要选规则引擎,我推荐从轻量级开始。先用表达式引擎(比如Aviator、QLExpress)+ 配置中心(Nacos、Apollo)。等规则超过200条,逻辑复杂了,再考虑升级到Drools。别一开始就上重型武器,那是给自己找麻烦。

好了,这一章就聊到这儿。规则引擎的演进,说白了就是「从复杂到简单,从重量到轻量」的过程。下一章,我会带你手写一个轻量级规则引擎,看看它到底是怎么工作的。

专注资料整理