规则引擎(yidun-checker-rule)
把「客户配置风控条款」的诉求,翻译成一次请求上的布尔判定 + 异步处置动作。
1. 业务定位
规则(Rule)= 若干条件(Condition)+ 命中后的动作(Action);规则归入规则集(RuleSet),按优先级执行。
- 上游:策略中台按
ruleSetCode调用执行面 Dubbo(execute/executeV2/executeV3/executeRulesBatched);执行上下文中的prepro.*已由预处理准备好。 - 下游:命中结果三分类回传;带动作的规则经 Kafka 触发加名单、点水任务、信用评分;命中明细进 ClickHouse 做统计。
2. 架构与模块划分
| 模块 | 类型 | 职责 |
|---|---|---|
common、domain | jar | 枚举/常量、DO/BO/上下文 |
service/base、service/business | jar | DAO/Manager/缓存、业务服务 |
management/dubbo-api + dubbo-provider | Dubbo | 规则/条件/动作/规则集 CRUD 与状态流转 |
execution/dubbo-api + dubbo-provider | Dubbo | 执行入口、规则集缓存、结果组装 |
cache/dubbo-provider | Dubbo | 把 DB 配置转成可执行模型 ClientRuleSet 并缓存 |
rulesdk/rule-client | jar | 内嵌求值 SDK:条件组合、QLExpress |
mq | app | Kafka 消费执行异步动作 |
scheduler | app | 命中统计任务 |
yidun-mplatform-rule-contract | jar | 跨层共享契约 |
3. 核心链路
执行侧的三条纪律:
- 执行期不查 DB:规则集配置全部来自
cache模块推送的可执行模型。 - 求值有硬超时:QLExpress 沙箱单次 100ms,避免一条复杂表达式拖垮整个请求。
- 动作不阻塞判定:命中后的处置一律走 Kafka,判定线程只负责算出结果。
4. 关键数据模型
| 对象 | 说明 |
|---|---|
RuleInfo | 规则主体,含状态、优先级、所属规则集 |
RuleCondition | 条件,支持 AND / OR / 命中 N 条 / 自定义表达式 |
RuleAction | 动作:加名单(ListSourceEnum.RULE_HIT)、点水任务、信用评分 |
RuleSet | 规则集合,按优先级排序执行 |
ClientRuleSet | 缓存层的可执行模型,由 RuleSetCacheService 生成 |
规则状态机:未上线(1) → 预上线(2) → 已上线(3) → 已失效(4) / 已锁定(5) / 已失效·熔断(6)。
5. 存储与中间件
| 组件 | 用途 |
|---|---|
| MySQL | 规则/条件/动作/规则集配置与快照 |
| Redis + 本地缓存 | 可执行规则集模型(common/validate 两套 Guava 缓存) |
| Kafka | 命中明细、统计、异步动作 |
| ClickHouse | 命中统计与报表 |
| QLExpress | 条件表达式求值(沙箱) |
6. 设计模式与扩展点
| 扩展点 | 位置 | 说明 |
|---|---|---|
| 条件组合模式 | RuleSetHandler → RuleHandler → ConditionHandler | 新增组合方式需扩展 handler |
| 表达式引擎 | QlExpressServiceV2 | 单例沙箱,操作符集中管理 |
| 动作处理器 | AbstractRuleActionExecuteHandler | 新增动作类型实现子类并注册 |
| 快照 | TakeSnapShot / SnapShotInterceptor | 规则变更留痕,支持对比与回滚 |
7. 上下游依赖
| 方向 | 模块 | 说明 |
|---|---|---|
| 上游 | mplatform-strategy | 按 ruleSetCode 调用执行面 |
| 上游 | checker-preprocess | 提供 prepro.* 富化字段 |
| 上游 | 策略中心 / 客户自定义规则控制台 | 经 operatorSite 区分管理入口 |
| 下游 | checker-namelist | 加名单动作写名单库 |
| 下游 | mplatform-clickhouse | 命中统计 |
| 下游 | mplatform-meta | fieldCode → jsonPath、风险标签/等级缓存 |
| 下游 | union-admin | 配置变更操作日志 |
8. 工程约束与变更红线
- 规则状态流转必须校验:删除前校验
deleteAbleStatusList,上线依赖命中率与验证时长准则。 - 执行期禁止直查数据库,缓存未命中时降级而非回源。
- 动作必须幂等:Kafka 至少一次投递,重复消费不能重复加名单。
- 表达式改动需回归:条件语义变化会直接改变线上拦截率,必须用试运行验证。
- 多入口权限隔离:
operatorSite决定是策略中心还是客户自定义,越权修改是安全事故。
9. 关键代码索引
| 主题 | 路径 | 说明 |
|---|---|---|
| 规则管理 | yidun-checker-rule/management/dubbo-provider/src/main/java/.../RuleInfoMgmtServiceImpl.java | CRUD 与状态流转 |
| 执行核心 | yidun-checker-rule/execution/dubbo-provider/src/main/java/.../RuleExecuteService.java | 取缓存、并行执行、组装、投递 |
| 规则集缓存 | yidun-checker-rule/cache/dubbo-provider/src/main/java/.../RuleSetCacheService.java | DB → ClientRuleSet |
| 条件求值 | yidun-checker-rule/rulesdk/rule-client/src/main/java/.../v2/QlExpressServiceV2.java | 沙箱表达式引擎 |
| 动作消费 | yidun-checker-rule/mq/src/main/java/.../RuleActionConsumer.java | 异步处置 |
| 状态枚举 | yidun-checker-rule/yidun-mplatform-rule-contract/src/main/java/.../RuleStatusEnum.java | 规则状态机 |
10. 排查要点
| 现象 | 定位 | 结论 |
|---|---|---|
| 规则配了但不命中 | 看条件引用的字段在执行上下文里是否有值 | 多为预处理未产出该字段,或字段 code 写错 |
| 命中但没动作 | 看动作消息是否投递、消费是否堆积 | 动作异步执行,回包不含结果 |
| 命中率突然下降 | 看规则集缓存版本与规则状态 | 缓存未刷新或规则被下线 |
| 执行慢 | 看单条规则表达式耗时 | 表达式过于复杂触及 100ms 超时 |
| 试运行规则不生效 | 确认规则状态 | 预上线只产生试命中,不参与处置 |