自用笔记。规则的「燃料」从哪来、怎么分流到下游。
关联:03-Risk 决策三层模块(总图)· 01-Risk 架构总览(系统怎么跑)· 02-Holmes 平台业务全景(Scene→L3→Feature)· 08-Risk 值班指南(超时/通过率怎么落到 feature)

一句话:Feature = 规则表达式里的变量;请求时按配置取值,不是写死在代码里。


1. 本文在架构里讲哪一块(模块交互)

总图见 03-Risk 决策三层模块
相对 01-Risk 架构总览:总览讲整条决策系统;本篇讲解「特征子系统」(上图橙色)——规则要变量时,数从哪个模块来、怎么配、怎么执行。

模块职责谁讲
credit_risk_engine外层工作流,调度 anti_fraud 等节点01-Risk 架构总览
risk-antifraud内层规则 DAG,L3 表达式求值架构总览 + 02-Holmes 平台业务全景 > 四、策略层级模型
risk_feature_sdk + risk_feature_core按配置取出/算出 Feature 值本篇
HBase/名单/Gateway…core 的下游本篇 execute_engine 分流

决策侧负责「判」;本篇负责「数从哪来」(特征模块)。


二、配置表 vs 注册表(用时间线理解)

时刻 0:服务启动(加载配置)

risk_feature_core 进程起来时,各个 .go 文件的 init() 自动跑:

RegisterExecutor("HbaseCommonExecutor", &HbaseCommonExecutor{})
RegisterExecutor("CheckListExecutor", &CheckListExecutor{})
RegisterExecutor("SimpleOuterExecutor", &SimpleOuterExecutor{})
...

结果:内存里有一本字典

"HbaseCommonExecutor"  →  某个结构体对象
"CheckListExecutor"    →  另一个结构体对象
...

注册表

  • 没有用户请求
  • 不读 risk_feature_new_tab
  • 只是把「代码里有哪些取数插件」装进进程

时刻 1:在线请求(每次用户来都走)

用户支付 → 风控规则要变量,例如 is_new_device

1. 去配置表 risk_feature_new_tab 查 is_new_device 这一行
   → execute_engine = "HbaseCommonExecutor"
   → script = 表名/rowkey 等参数
 
2. 拿字符串 "HbaseCommonExecutor" 去【时刻0 备好的字典】里找
   → 找到 &HbaseCommonExecutor{}
 
3. 调它的 Execute(script...)
   → 读 HBase / 调名单 / 外调…
   → 返回 true/false 或一个数
 
4. 规则用这个数做判断

两张表怎么「对上」

配置表(MySQL,人/Holmes 写)          注册表(内存,代码启动写)
─────────────────────────          ─────────────────────────
feature: is_new_device              "HbaseCommonExecutor" → 对象A
engine:  HbaseCommonExecutor  ──join──►  用名字字符串对上
script:  {...}
定义
配置表配置表只是「每个变量怎么取」的配方行
注册表内存中的 mapping, feature_core 进程内;定义executor实现

有的 executor 不进注册表

字典里这个 engine 名(常见):

GetExecutor → struct.Execute → 得到特征值

字典里没有、或配置故意走旁路(Root / SdkLocal / UnderWriting):

不调这本字典
值从「这次请求里已经有的东西」抠:
  - 请求 header/body 字段(Root)
  - 业务方 SDK 本地 callback(SdkLocal)
  - 上游 sisout 输出(UnderWriting)

所以「旁路」不是第三张表,是:这个值不用 feature_core 的插件字典


四、execute_engine 分流

先查表 risk_feature_new_tab

类型走哪终点
CheckList / HbaseCommon / FeatureReaderfeature_core 注册表 → 本地 executorHBase / Redis / 名单等
SimpleOuter / template / 部分 ScriptExecutor注册表 → executor 内再转发gateway → 常落到 Unicorn
RootExecutor不进注册表event/header 抠字段
SdkLocalCallbackExecutor不进注册表业务方本地 callback
UnderWritingParamExecutor不进注册表sisout 上游输出字段

转发链(排障):

feature → execute_engine/script → gateway method → cug_api_tab → tenant::func → Unicorn → 下游

五、值班相关

  1. 通过率/时延 → hit_l3_group 定位叶子规则
  2. 规则依赖哪些 Feature
  3. Feature 超时/缺数(StdErrTimeout / StdErrMissingData
  4. skill risk-feature-callchain-trace 顺着配置追终点

六、工具

用途工具
追调用链risk-feature-callchain-trace
查 feature 配置risk-rds-queryrisk_feature_new_tab
查 gateway 路由cug_api_tab
查 Unicornrisk-af-unicorn-platform

相关