2、架构设计:实时风控引擎的整体架构、分层设计

好,咱们直接进入正题。实时风控引擎这东西,说白了就是要在几百毫秒内判断一笔交易是不是有问题。我见过不少团队一上来就堆代码,结果跑起来发现延迟高得离谱,或者规则根本没法灵活调整。嗯,这里的关键在于——先把架子搭对。

我个人习惯,做架构设计前先画一张大图。把整个系统拆成三层:接入层、决策层、数据层。每一层各司其职,层与层之间通过轻量级接口通信。这样后期不管是加规则还是换模型,都不至于牵一发动全身。

核心原则: 高内聚、低耦合。每一层只关心自己的事,别越界。

2.1 整体架构概览

先看这张图,这是我手绘的实时风控引擎分层架构。你想想看,一个请求从进来到最后出结果,中间要经过多少道工序?

实时风控引擎分层架构图 接入层 HTTP/GRPC 网关 | 协议转换 | 流量整形 | 鉴权 请求排队 | 参数校验 | 上下文构建 → 统一入口,屏蔽后端复杂性 决策层 规则引擎 条件匹配 | 阈值判断 优先级调度 模型引擎 特征提取 | 模型推理 分数输出 名单引擎 黑/白/灰名单 高速缓存匹配 → 核心决策逻辑,三引擎并行/串行执行 数据层 实时特征库 Redis/SSDB 历史事件库 ClickHouse/ES 名单存储 Redis Cluster 模型仓库 HDFS/S3 → 数据底座,支撑决策层的实时查询

这张图我画了好几个版本才定下来。你看,接入层在最上面,像个门卫;决策层在中间,是大脑;数据层在最底下,是仓库。每一层各司其职,互不干扰。

2.2 接入层设计

接入层是风控系统的第一道关卡。我见过有些团队把接入层做得特别重,结果成了瓶颈。其实接入层就干三件事:收请求、做校验、转格式。

核心职责:

  • 协议适配: 支持 HTTP、GRPC、MQ 等多种接入方式。我个人习惯用 GRPC 做内部服务间通信,HTTP 留给外部调用。
  • 流量整形: 限流、熔断、降级。别让突发流量把决策层打垮。
  • 上下文构建: 把原始请求转成统一的内部事件对象。比如把 JSON 里的 user_id、amount、ip 等字段提取出来,组装成标准格式。
  • 鉴权与验签: 确保请求来源合法。我在项目中遇到过有人伪造请求来试探风控规则,所以这一步不能省。

小技巧: 接入层尽量无状态,方便水平扩展。我一般用 Nginx + Lua 做前置网关,或者直接用 Envoy 做 sidecar。

2.3 决策层设计

决策层是风控引擎的心脏。这里跑着三个核心引擎:规则引擎、模型引擎、名单引擎。它们可以串行执行,也可以并行执行,取决于你的业务场景。

2.3.1 规则引擎

规则引擎是最传统也最直观的风控手段。说白了就是一堆 if-else 的集合,但你不能真在代码里写死。我建议用规则引擎框架,比如 Drools、EasyRules,或者自己写一个简单的表达式引擎。

规则示例:

规则:单笔交易金额超过 5000 元且 IP 归属地为高风险地区
动作:拒绝交易,返回码 1001
优先级:高

规则引擎的核心是可配置化。运营人员应该能通过后台页面新增、修改、启停规则,而不需要开发改代码。我曾经在一个项目中,因为规则写死在代码里,每次调整都要发版,被运营同事吐槽了整整半年。

2.3.2 模型引擎

模型引擎负责跑机器学习模型。比如逻辑回归、XGBoost、神经网络等。模型引擎的输入是特征,输出是一个风险分数。

模型引擎的工作流程:

  1. 从请求上下文中提取原始特征(如金额、时间、设备指纹)
  2. 调用特征工程模块,做归一化、离散化、交叉特征等处理
  3. 加载模型文件,执行推理
  4. 输出风险分数(0-100),分数越高风险越大

注意: 模型引擎的延迟是关键。我见过一个团队用 Python 做模型推理,单次推理要 200ms,整个风控链路直接超时。后来换成 ONNX Runtime 或者 TensorRT,延迟降到了 10ms 以内。

2.3.3 名单引擎

名单引擎是最简单但最有效的风控手段。黑名单直接拒绝,白名单直接放行,灰名单走人工审核。

名单存储方案对比:

存储方案 查询延迟 容量 适用场景
Redis 单机 <1ms 百万级 小规模名单
Redis Cluster <2ms 千万级 大规模名单
本地缓存 + Redis <0.1ms 十万级 高频热点名单

我个人习惯用本地缓存 + Redis 的双层架构。热点名单放本地,冷数据查 Redis。这样既能保证速度,又能支持大规模名单。

2.4 数据层设计

数据层是风控系统的底座。没有数据,规则和模型都是空中楼阁。

数据层包含几个关键组件:

  • 实时特征库: 用 Redis 或 SSDB 存储用户的实时行为特征,比如最近 5 分钟的交易次数、登录地点等。
  • 历史事件库: 用 ClickHouse 或 Elasticsearch 存储历史风控事件,用于离线分析和模型训练。
  • 名单存储: 黑/白/灰名单的持久化存储,一般用 Redis Cluster。
  • 模型仓库: 存放训练好的模型文件,支持版本管理和灰度发布。

关键设计原则: 数据层要支持高并发读写。实时特征库的 QPS 可能达到几十万,所以必须用缓存,而且要做好缓存穿透、缓存雪崩的防护。

2.5 核心模块拆解

咱们把三个引擎再拆细一点,看看里面到底有什么。

规则引擎内部结构

  • 规则解析器: 把配置的规则文本解析成可执行的表达式树
  • 规则匹配器: 遍历所有规则,找到匹配的规则
  • 动作执行器: 执行匹配规则对应的动作(拒绝、放行、人工审核)
  • 优先级调度器: 决定规则的执行顺序,高优先级规则先执行

模型引擎内部结构

  • 特征提取器: 从请求上下文中提取原始特征
  • 特征工程模块: 做特征处理,比如缺失值填充、标准化、One-Hot 编码
  • 模型加载器: 从模型仓库加载模型文件,支持热加载
  • 推理执行器: 执行模型推理,输出风险分数

名单引擎内部结构

  • 名单加载器: 从 Redis 或本地缓存加载名单数据
  • 匹配器: 支持精确匹配、前缀匹配、正则匹配
  • 缓存管理器: 管理本地缓存和 Redis 缓存的一致性
  • 过期策略: 名单条目有过期时间,自动清理过期数据

避坑指南: 我曾经在名单引擎里用过全量加载的方式,结果名单到了 500 万条时,内存直接爆了。后来改成按需加载 + LRU 淘汰,问题才解决。

2.6 架构设计的几个关键点

最后,我总结几个架构设计时容易踩的坑:

  • 别把决策层做得太重: 每个引擎只做自己的事,别混在一起。规则引擎别去调模型,模型引擎别去查名单。
  • 异步化处理: 对于非核心链路(比如日志记录、异步通知),用消息队列解耦,别阻塞主流程。
  • 可观测性: 每一层都要有完善的监控和日志。我习惯在接入层、决策层、数据层都埋点,记录耗时和结果。
  • 灰度发布: 新规则、新模型先灰度一小部分流量,观察效果再全量。别一上来就全量推,容易翻车。

嗯,架构设计这块就聊这么多。记住,好的架构不是一次设计出来的,而是在迭代中不断演进的。你先把这三层架子搭好,后面加功能、调性能都会轻松很多。


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