规则引擎基础:规则是怎么跑起来的?

什么是规则引擎?别把它想复杂了

很多人一听到「规则引擎」这个词,就觉得是个庞然大物。说白了,规则引擎就是一个专门处理规则的组件。它接收输入数据,判断这些数据符不符合事先定义好的条件,然后决定要做什么动作。

我在做工业监控项目时,设备有几十个参数。温度不能超过 85°C,湿度不能高于 60%,振动幅度也有阈值。一开始我们直接用 if-else 硬编码,结果每次业务方提一个新规则,就得改代码、重新上线。半年下来,代码里塞满了各种逻辑,谁也改不动了。

后来我们引入了规则引擎,情况完全变了。业务人员自己在界面上配置规则,系统自动执行。上线一个新规则只需要几分钟,而不是几天。

规则引擎的核心组件

  • 规则库:存放所有规则的地方,说白了就是规则清单
  • 事实:输入给引擎的数据,比如当前温度、用户行为记录
  • 执行引擎:匹配事实与规则,决定哪些规则该被触发
  • 动作:规则触发后的行为,发邮件、写日志、调接口

你想想看,一个系统里如果只有三五条规则,用 if-else 确实够用。但规则超过 50 条,甚至上百条时,手写条件分支就是噩梦了。规则引擎这时候就体现出价值了——它将条件判断逻辑从核心代码中抽离出来,独立管理。

举个例子。一个电商平台的异常交易检测,可能有几十条规则:单笔金额超过 10 万标记为高风险、同一收货地址 24 小时内下单超过 3 次标记为异常、用户异地登录后立即下单标记为可疑……把这些规则塞进代码里,维护成本太高了。

规则定义方式:阈值与逻辑表达式

规则怎么定义?常见的就两种方式。嗯,我这里说的「常见」是指实际工程中真正会用的方式。

阈值规则

阈值规则最简单,也是最常用的。就是把数值和预设的临界值比较。比如 CPU 使用率大于 90% 就报警。

阈值规则不一定是单边儿的,也可以有范围。我记得有一次做服务器监控,业务方要求 CPU 使用率不能低于 10% 也不能高于 85%,低于 10% 要检查进程是不是挂了,高于 85% 要扩容预警。这就是双阈值。

阈值类型 定义方式 应用场景
单阈值 value > threshold 或 value < threshold 温度过高报警、内存不足报警
双阈值 low < value < high 或 value < low || value > high 心率异常检测、流量波动检测
趋势阈值 rate of change > limit 或斜率超过阈值 环比暴增检测、梯度下降检测

代码写起来也很直白:

// 伪代码示例:阈值规则
if (cpu_usage > 90.0) {
    trigger_alarm("CPU过高", cpu_usage);
    return "high_risk";
}
if (memory_usage > 85.0) {
    trigger_alarm("内存过高", memory_usage);
    return "medium_risk";
}
return "normal";

不过这种单纯卡阈值的做法有一个坑:临界值附近的数据容易误报。比如阈值设为 85,结果数值是 85.1,就会触发一次报警。但实际系统波动一下是很正常的。

我通常的做法:阈值规则配合一个「滞后区」。比如高于 85 触发报警,但必须低于 80 才能解除报警。这样能避免反复触发和恢复的抖动现象。

逻辑表达式规则

实际业务不会满足于单一阈值。你会碰到这种情况:当 CPU 大于 80% 并且内存大于 75% 并且持续超过 5 分钟——这个时候才判定为异常。

逻辑表达式就是把这些条件组合起来。常见的操作符包括:

  • AND (&&):所有条件同时成立才触发
  • OR (||):任何一个条件成立就触发
  • NOT (!):条件不成立时触发
  • 组合:括号改变优先级,像数学表达式一样

我用过的一个实际例子,判断一个用户行为是否异常,规则是这样的:

// 逻辑表达式规则示例
if (login_ip_city != usual_city 
    && (transaction_amount > 50000 || transaction_count > 3) 
    && time_since_last_login > 7_days) {
    mark_as_suspicious(user_id);
}

这个规则的意思是:如果用户本次登录的城市和常用的不一样,并且交易金额超过 5 万或者交易次数超过 3 次,而且距离上次登录已经超过 7 天——那么判定为可疑行为。

我曾经被这个坑过:在逻辑表达式规则中,条件的顺序会影响性能。应该把计算代价低、过滤能力强的条件放在前面。比如先检查 IP 是否变化(一次字符串比较),再检查交易金额(需要查数据库)。这样大部分规则在第一步就被过滤掉了,后边不用执行。

业务规则与系统规则:别把它们混在一起

这是很多项目刚开始时容易犯的错误。把业务逻辑和系统规则写在同一个文件,甚至同一个 if 语句里。为什么不能混?因为它们变了,变化频率和责任人完全不同。

对比维度 业务规则 系统规则
谁定义的 产品经理、运营人员、业务专家 开发工程师、运维工程师
变化频率 高频,可能每天调整 低频,稳定为主
示例 单笔金额超过 10 万标记为高风险 引擎执行超时 5 秒则终止并写入异常日志
校验方式 业务测试、A/B 测试 单元测试、压力测试
存放位置 数据库、配置文件、规则管理平台 代码库、配置中心

我参与过一个金融项目,团队一开始把业务规则硬编码在系统里。业务方想要调整一下规则:把最高风险金额从 10 万改成 8 万。结果需要开发人员提 MR、走 CR、排上线窗口……前后花了三天。业务方急得跳脚,说「你们效率也太低了」。

后来我们重新设计了规则架构,把业务规则抽出来放进了规则引擎。业务人员自己在管理后台改参数,改完立刻生效。系统规则保持不变,还是由开发团队维护。

我个人习惯:两条线。业务规则走「热加载」,系统规则走「冷部署」。业务规则放数据库或配置文件,支持不停机更新。系统规则写在代码里,一定要走发布流程。这样既能保证业务敏捷性,也能守住系统的稳定性底线。

简单总结一下:业务规则是「做什么」,系统规则是「怎么做」。前者由业务驱动,后者由工程保障。两条线独立演进,不要搅在一起。

规则引擎基础结构 输入数据(事实) 规则执行引擎 规则库 阈值规则 逻辑表达式规则 规则来源 业务规则(热加载) 系统规则(冷部署) 输出动作 常见动作类型 • 触发报警 • 发送通知 • 拦截操作 • 记录日志 • 调用外部接口

图上展示了规则引擎的基本流程:输入数据进入执行引擎,引擎从规则库中取规则进行匹配,匹配命中后输出指定动作。规则库本身又分为业务规则和系统规则两条线,它们的来源和维护方式完全不同,这一点在实际工程中必须分清楚。