灰度切流策略框架设计
本文介绍了一套基于策略模式与配置驱动的通用灰度发布框架。该框架支持白名单、黑名单、百分比等多种切流策略,并允许策略组合使用。通过配置热更新实现零代码侵入,解决了传统灰度发布中代码耦合度高、调整需发版等问题。框架采用策略模式设计,将每种灰度策略封装为枚举+处理器形式,支持动态加载配置和实时生效。业务方只需调用统一接口传入业务码和目标ID即可完成灰度决策,实现了"一行代码接入、配置动态生效&
一套基于策略模式 + 配置驱动的通用灰度发布框架,支持白名单、黑名单、百分比、组合策略等多种切流模式,配置热更新零代码侵入。
1. 背景与问题
在大型业务系统中,新功能上线通常不能一蹴而就地全量放开,而是需要经历"内部验证 → 小范围灰度 → 逐步放量 → 全量切流"的渐进式发布过程。传统的 if-else 硬编码方式存在以下问题:
| 问题 | 描述 |
|---|---|
| 代码侵入强 | 每个灰度场景都需要写一套判断逻辑,散落在各业务代码中 |
| 调整需发版 | 修改白名单或百分比需要重新发布应用 |
| 缺乏一致性 | 不同场景的灰度实现方式五花八门,难以统一管控 |
| 无法一键熔断 | 发现问题时无法快速关闭灰度开关 |
| 难以组合 | 无法灵活组合多种灰度策略(如"白名单 + 百分比") |
本框架的核心目标:一行代码接入、配置动态生效、策略可组合、一键可熔断。
2. 整体架构
┌─────────────────────────────────────────────────────────────┐
│ 业务调用方 │
│ grayStrategyService.isPassGrayStrategy( │
│ "YOUR_BIZ_CODE", targetId, params) │
└────────────────────────┬────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ GrayStrategyServiceImpl │
│ │
│ ① 根据 bizCode 查询远程配置中心,获取 GrayStrategyConfig │
│ ② 检查 switchOn 总开关 │
│ ③ 反序列化 modeList,逐个执行策略 Handler │
│ ④ all pass → true ; any fail → false │
│ ⑤ try-finally 打印决策 digest 日志 │
└────────────┬────────────┬────────────┬──────────────────────┘
│ │ │
┌────────▼──┐ ┌──────▼───┐ ┌────▼──────────┐
│ Handler A │ │Handler B │ │ Handler C │ ...
│ (白名单) │ │(百分比) │ │(黑名单等) │
└───────────┘ └──────────┘ └───────────────┘
核心决策流程:
- 业务方传入
bizCode(灰度业务码)、targetId(通常是商户 ID)、params(维度参数) - 根据
bizCode从配置中心加载GrayStrategyConfig - 如果配置不存在或
switchOn=false,直接返回默认结果 - 遍历
modeList中的策略模式,逐个执行对应的Handler - 任意一个 Handler 不通过,整体不通过(AND 语义)
- 全部通过,返回
true
3. 核心组件详解
3.1 配置模型 —— GrayStrategyConfig
每一条灰度配置包含 5 个字段:
| 字段 | 类型 | 说明 | 示例 |
|---|---|---|---|
bizCode |
String | 灰度业务标识,定位到具体业务场景 | "SUPPLY_B2B_MEMBER_WITH_REGISTER_FROM" |
switchOn |
String | 总开关,控制该场景灰度是否启用 | "true" / "false" |
modeList |
String | JSON 数组,策略模式列表,支持多策略组合 | ["WHITE_LIST","UID_PERCENTAGE"] |
ruleMap |
String | JSON 对象,白名单/黑名单的维度规则 | {"userId":["uid1","uid2"],"instCode":["Z05"]} |
cutPercentage |
String | 百分比切流比例(0-100) | "10" 表示 10% |
关键设计 —— modeList 是数组: 同一个业务场景可以叠加多种策略模式。比如同时配置 ["WHITE_LIST","UID_PERCENTAGE"],表示先过白名单、再过百分比,全部满足才算通过。
配置存储在远程配置中心(如 ComPara),修改后即时生效,无需发版。
3.2 策略模式枚举 —— GrayStrategyModeEnum
将每种灰度策略封装为 枚举值 + Handler 的形式:
┌─────────────────────────────┬───────────────────────────────────────────────────┐
│ 枚举值 │ 描述 │
├─────────────────────────────┼───────────────────────────────────────────────────┤
│ ALL_PASS │ 全量放行模式 │
│ WHITE_LIST │ 白名单模式(所有维度必须同时命中,AND 语义) │
│ BLACK_LIST │ 黑名单模式(任意维度命中即拦截,OR 语义) │
│ UID_PERCENTAGE │ UID 分表位百分比切流(确定性,同一用户结果恒定) │
│ REFERENCE_UID_PERCENTAGE │ 引用 UID 百分比切流(hashCode 分桶,非标准 UID 用) │
│ WHITE_LIST_ANY_MATCH_ENOUGH │ 宽松白名单(任意一个维度命中即通过,OR 语义) │
│ WHITE_LIST_WITH_PERCENTAGE │ 白名单+百分比(核心维度直通,非核心维度再过百分比) │
└─────────────────────────────┴───────────────────────────────────────────────────┘
设计亮点 —— 枚举即路由表: 枚举的构造函数第三个参数直接持有对应的 Handler 实例:
WHITE_LIST("WHITE_LIST", "白名单模式", new WhiteListStrategyHandler()),
调用时通过 GrayStrategyModeEnum.getByCode(mode).getHandler() 即可获取处理器,省去了工厂类或 Map 映射。
3.3 策略处理器接口 —— GrayStrategyHandler
public interface GrayStrategyHandler {
int PERCENTAGE_0 = 0;
int PERCENTAGE_100 = 100;
/**
* @param config 灰度策略配置(含 ruleMap、cutPercentage 等)
* @param targetId 切流目标 ID(通常是商户 userId)
* @param param 运行时维度参数(如 userId、instCode、label 等)
* @return true: 通过灰度决策 | false: 不通过
*/
boolean handle(GrayStrategyConfig config, String targetId, Map<String, String> param);
}
三个参数的职责明确:
- config:该场景的完整灰度配置,Handler 按需读取 ruleMap、cutPercentage 等字段
- targetId:切流目标,通常传商户 userId
- param:运行时维度参数,与 ruleMap 中的 key 对应用于匹配
3.4 调用方接口 —— GrayStrategyService
提供两个重载方法和一系列参数构建工具:
// 核心方法(defaultResult 默认 false)
boolean isPassGrayStrategy(String bizCode, String targetId, Map<String, String> params);
// 支持自定义默认结果的方法
boolean isPassGrayStrategy(String bizCode, String targetId, Map<String, String> params,
boolean defaultResult);
// 参数构建工具方法(static)
static Map<String, String> buildUidParamMap(String userId);
static Map<String, String> buildLabelParamMap(String label);
static Map<String, String> buildBizSceneParamMap(String bizScene);
static Map<String, String> buildInstCodeParamMap(String instCode);
static Map<String, String> buildParamMap(String key, String value);
defaultResult** 参数的含义:** 当配置不存在(即配置中心没有该 bizCode 的记录)时,返回什么默认值。一般传 false(保守,走老流程),也可以按业务需要传 true。
4. 七种策略模式详解
4.1 ALL_PASS —— 全量放行
语义: 无条件放行,所有请求都通过。
适用场景: 灰度验证已结束,需要全量上线时,将 modeList 改为 ["ALL_PASS"] 即可。
实现: 直接返回 true。
4.2 WHITE_LIST —— 严格白名单(AND 语义)
语义: ruleMap 中所有维度都必须命中白名单,才算通过。
决策流程:
传入参数: {userId: "A", instCode: "Z05"}
配置: ruleMap = {userId: ["A","B"], instCode: ["Z05"]}
遍历 ruleMap:
① userId 维度: param["userId"]="A" 在白名单 ["A","B"] 中 → 通过
② instCode 维度: param["instCode"]="Z05" 在白名单 ["Z05"] 中 → 通过
所有维度通过 → 返回 true
传入参数: {userId: "A", instCode: "Z99"}
配置: ruleMap = {userId: ["A","B"], instCode: ["Z05"]}
遍历 ruleMap:
① userId 维度: 通过
② instCode 维度: param["instCode"]="Z99" 不在白名单 ["Z05"] 中 → 不通过
存在维度不通过 → 返回 false
注意: 如果传入参数中缺少某个维度的值,直接返回 false。白名单是"证明你行"的逻辑,缺少证据即为不通过。
适用场景: 精确控制特定商户,需要同时满足多个维度条件。
4.3 BLACK_LIST —— 黑名单(OR 语义)
语义: ruleMap 中任意一个维度命中黑名单,即被拦截。
决策流程:
传入参数: {userId: "A", instCode: "Z05"}
配置: ruleMap = {userId: ["C","D"], instCode: ["Z99"]}
遍历 ruleMap:
① userId 维度: param["userId"]="A" 不在黑名单 ["C","D"] 中 → 不拦截
② instCode 维度: param["instCode"]="Z05" 不在黑名单 ["Z99"] 中 → 不拦截
全部未命中 → 返回 true(放行)
关键设计差异: 如果传入参数中缺少某个维度的值,黑名单模式选择 continue(跳过,不拦截),而非返回 false。这与白名单相反:黑名单是"证明你不行",缺少证据就不拦截。
适用场景: 排除特定商户,如已知有问题的商户 ID 需要暂时屏蔽新流程。
4.4 UID_PERCENTAGE —— UID 分表位百分比切流
语义: 根据 userId 的分表位(0-99)判断是否命中灰度比例。
决策流程:
1. 从配置读取 cutPercentage(如 "10")
2. 通过 DBPrimaryKeyUtil.getUserPartitionByUserId(userId) 获取分表位
3. 判断: userPartition < cutPercentage → 通过
设计亮点 —— 确定性: 使用分表位而不是 Random.nextInt(),保证了同一用户多次请求的结果恒定。这是灰度切流的关键要求——用户不能一会儿走新流程一会儿走老流程。
分表位算法内部还兼容了压测 UID(倒数第二位可能是字母 A-J),会做字母→数字的替换处理。
适用场景: 按比例灰度放量,如先放量 5%,观察后逐步提升到 10%、50%、100%。
4.5 REFERENCE_UID_PERCENTAGE —— 引用 UID 百分比切流
语义: 与 UID_PERCENTAGE 类似,但分桶算法不同。
关键区别:
| 模式 | 分桶算法 | 适用场景 |
|---|---|---|
| UID_PERCENTAGE | 分表位(DB 内部 ID 格式) | 标准 ipay 内部 UID |
| REFERENCE_UID_PERCENTAGE | hashCode() % 100 |
非 ipay 格式的引用 ID(如平台商的 seller ID) |
设计亮点 —— 模板方法模式: 继承 PercentageStrategyHandler,只覆写 getUserPartitionByUserId 方法:
public class ReferenceUidPercentageStrategyHandler extends PercentageStrategyHandler {
@Override
protected int getUserPartitionByUserId(String referenceUserId) {
return Math.abs(referenceUserId.hashCode() % 100);
}
}
父类定义了百分比判定的骨架流程,子类只需替换分桶算法。
4.6 WHITE_LIST_ANY_MATCH_ENOUGH —— 宽松白名单(OR 语义)
语义: ruleMap 中任意一个维度命中白名单,即算通过。
决策流程:
传入参数: {userId: "A", instCode: "Z99"}
配置: ruleMap = {userId: ["A","B"], instCode: ["Z05"]}
遍历 ruleMap:
① userId 维度: param["userId"]="A" 在白名单 ["A","B"] 中 → 命中!
任意一条命中 → 返回 true(无需继续检查 instCode)
额外能力 —— 通配符 *: 如果某个维度的白名单列表包含 "*",则该维度无条件通过:
配置: ruleMap = {instCode: ["*"]}
传入参数: {instCode: "任意值"}
→ 命中通配符,直接通过
与严格白名单的对比:
| 对比维度 | WHITE_LIST(严格) | WHITE_LIST_ANY_MATCH_ENOUGH(宽松) |
|---|---|---|
| 语义 | 所有维度都要命中 | 任意维度命中即可 |
| 逻辑 | AND | OR |
| 缺少维度参数 | 返回 false | 不影响(其他维度命中即可) |
| 通配符支持 | 无 | 支持 * |
钩子方法设计: hintPercentageAfterMatch() 是一个钩子,当前实现直接返回 true,但为子类留了扩展点。
4.7 WHITE_LIST_WITH_PERCENTAGE —— 白名单 + 百分比
语义: 先做白名单匹配(OR 语义),命中后根据维度类型决定是否再做百分比淘汰。
核心逻辑(覆写钩子方法):
白名单命中后:
├── 命中的维度是核心维度 (userId / maInnerId)
│ → 直接放行,不走百分比
│
└── 命中的维度是非核心维度 (instCode / label 等)
→ 还需要过百分比随机淘汰
→ RandomUtils.nextInt(0, 101) <= cutPercentage → 通过
设计智慧 —— 维度优先级区分:
- 核心维度(userId、maInnerId):白名单精确到具体商户,确定性高,不需要百分比。配置了某个 userId 就一定放行该用户。
- 非核心维度(instCode、label 等):白名单覆盖范围大(如某个 instCode 下可能有大量商户),需要百分比来渐进放量,避免一次性放开太多。
百分比注意点: 这里的百分比用的是 RandomUtils.nextInt()(随机),与 UID_PERCENTAGE 的分表位(确定性)不同。这是有意为之——白名单阶段已经做了维度筛选,百分比阶段是对非核心维度的补充过滤,随机性可以接受。
5. 策略组合机制
modeList 支持配置多个策略模式,实现灵活组合:
5.1 多策略 AND 语义
配置示例:"modeList": ["WHITE_LIST","UID_PERCENTAGE"]
决策过程:先过白名单 → 再过百分比 → 全部通过才算通过
请求进入
│
▼
WHITE_LIST Handler
├── 不通过 → 返回 false
└── 通过 ↓
▼
UID_PERCENTAGE Handler
├── 不通过 → 返回 false
└── 通过 → 返回 true
5.2 单策略场景
配置示例:"modeList": ["WHITE_LIST_ANY_MATCH_ENOUGH"]
只走一种策略模式,通过即通过。
5.3 全量切流
配置示例:"modeList": ["ALL_PASS"]
等价于关闭灰度,所有请求都走新流程。也可以直接将 switchOn 设为 "true" 配合 ALL_PASS。
6. 核心决策引擎流程
private boolean doGrayDecide(String bizCode, String userId,
Map<String, String> params, boolean defaultResult) {
// 1. bizCode 为空 → 返回 defaultResult
if (Objects.isNull(bizCode)) {
return defaultResult;
}
// 2. 从配置中心查询 GrayStrategyConfig
GrayStrategyConfig strategyConfig = queryGrayStrategyConfig(bizCode);
// 3. 配置不存在 → 返回 defaultResult
if (Objects.isNull(strategyConfig)) {
return defaultResult;
}
// 4. 总开关关闭 → 返回 false(一键熔断)
if (!Boolean.parseBoolean(strategyConfig.getSwitchOn())) {
return false;
}
// 5. 解析 modeList
List<String> grayModes = JSONObject.parseObject(strategyConfig.getModeList(),
new TypeReference<List<String>>() {});
if (CollectionUtils.isEmpty(grayModes)) {
return false;
}
// 6. 遍历执行每个策略 Handler(AND 语义)
for (String grayMode : grayModes) {
GrayStrategyModeEnum modeEnum = GrayStrategyModeEnum.getByCode(grayMode);
if (Objects.isNull(modeEnum)) {
return false; // 不支持的模式 → 不通过
}
if (!modeEnum.getHandler().handle(strategyConfig, userId, params)) {
return false; // 任一策略不通过 → 整体不通过
}
}
return true; // 所有策略都通过
}
关键设计决策总结:
| 步骤 | 条件 | 结果 | 设计意图 |
|---|---|---|---|
| bizCode 为空 | 无法决策 | 返回 defaultResult |
兜底安全,由调用方决定 |
| 配置不存在 | 未配置灰度规则 | 返回 defaultResult |
未配置 != 拦截,尊重业务方的默认倾向 |
| switchOn=false | 主动关闭 | 返回 false |
一键熔断,紧急情况下快速回滚 |
| modeList 为空 | 无策略 | 返回 false |
有配置但无策略,保守处理 |
| 不支持的模式 | 配置错误 | 返回 false |
防止配置错误导致误放行 |
| Handler 不通过 | 策略拦截 | 返回 false |
AND 语义,任意失败即终止 |
7. 配置示例
示例 1:简单白名单(仅允许指定用户)
{
"grayBizCode": "MY_FEATURE_SWITCH",
"switchOn": "true",
"modeList": "[\"WHITE_LIST\"]",
"ruleMap": "{\"userId\":[\"2088123456\",\"2088789012\"]}",
"cutPercentage": "0"
}
调用方式:
grayStrategyService.isPassGrayStrategy(
"MY_FEATURE_SWITCH",
userId,
GrayStrategyService.buildUidParamMap(userId)
);
示例 2:白名单 + 百分比组合(白名单用户直通,非白名单用户按 instCode 10% 放量)
{
"grayBizCode": "MY_FEATURE_SWITCH",
"switchOn": "true",
"modeList": "[\"WHITE_LIST_WITH_PERCENTAGE\"]",
"ruleMap": "{\"userId\":[\"2088123456\"],\"instCode\":[\"Z05\"]}",
"cutPercentage": "10"
}
调用方式:
Map<String, String> params = new HashMap<>();
params.put("userId", userId);
params.put("instCode", instCode);
grayStrategyService.isPassGrayStrategy("MY_FEATURE_SWITCH", userId, params);
- userId 命中白名单 → 核心维度,直通
- instCode 命中白名单但 userId 未命中 → 非核心维度,10% 随机放量
- 都未命中 → 不通过
示例 3:全量切流
{
"grayBizCode": "MY_FEATURE_SWITCH",
"switchOn": "true",
"modeList": "[\"ALL_PASS\"]",
"ruleMap": "{}",
"cutPercentage": "0"
}
示例 4:黑名单排除(排除特定商户)
{
"grayBizCode": "MY_FEATURE_SWITCH",
"switchOn": "true",
"modeList": "[\"BLACK_LIST\"]",
"ruleMap": "{\"userId\":[\"2088problem1\",\"2088problem2\"]}",
"cutPercentage": "0"
}
示例 5:多策略组合(先过白名单,再过百分比)
{
"grayBizCode": "MY_FEATURE_SWITCH",
"switchOn": "true",
"modeList": "[\"WHITE_LIST\",\"UID_PERCENTAGE\"]",
"ruleMap": "{\"instCode\":[\"Z05\"]}",
"cutPercentage": "30"
}
- instCode 必须是 Z05(白名单 AND 语义)
- 且分表位 < 30(百分比切流)
- 两者都满足才通过
8. 灰度生命周期管理
一个完整的灰度切流应经历以下阶段:
阶段 1: 内部验证
配置: modeList=["WHITE_LIST"], ruleMap={userId: ["内部测试UID"]}
目标: 仅对内部用户开放
↓ 验证通过
阶段 2: 小范围灰度
配置: modeList=["WHITE_LIST_ANY_MATCH_ENOUGH"], ruleMap={instCode: ["Z05"]}
目标: 指定 instCode 下的商户开放
↓ 观察稳定
阶段 3: 渐进放量
配置: modeList=["WHITE_LIST_WITH_PERCENTAGE"], ruleMap={instCode: ["Z05"]}, cutPercentage="10"
目标: 非核心维度命中后 10% 放量
↓ 逐步提升 cutPercentage: 10 → 30 → 50 → 80
阶段 4: 全量切流
配置: modeList=["ALL_PASS"]
目标: 全量开放
↓ 运行稳定
阶段 5: 下线灰度代码
目标: 移除灰度判断逻辑,删除 ComPar配置,清理 GrayBizCodeEnum
重要提醒: 阶段 5 常常被忽略。灰度配置不是永久的,切流完成后要及时下线灰度代码和配置,否则代码中会残留大量无用的灰度判断逻辑,增加维护成本。
9. 设计模式总结
| 设计模式 | 应用位置 | 效果 |
|---|---|---|
| 策略模式 | GrayStrategyHandler + 7 种实现 |
不同灰度判定算法可独立变化,互不影响 |
| 模板方法模式 | PercentageStrategyHandler → ReferenceUidPercentageStrategyHandler |
复用百分比切流骨架,只替换分桶算法 |
| 模板方法模式 | AnyMatchEnoughWhiteListStrategyHandler → AnyMatchEnoughWhiteListAndPercentageStrategyHandler |
复用白名单匹配逻辑,只扩展命中后的百分比判断 |
| 枚举即路由表 | GrayStrategyModeEnum 持有 Handler 实例 |
省去工厂类,枚举值 = 策略码 + 处理器 |
| 配置驱动 | 配置中心存储 GrayStrategyConfig | 策略规则热更新,无需发版 |
| 组合模式 | modeList 数组 | 多个策略 AND 组合,实现精细化切流控制 |
10. 接入指南
10.1 新增灰度场景
Step 1: 在 GrayBizCodeEnum 中添加业务码枚举(可选,建议添加以获得编译期检查):
public enum GrayBizCodeEnum {
// ...
/** 你的业务场景描述 */
YOUR_BIZ_SCENE_CODE,
// ...
}
Step 2: 在配置中心(ComPara)添加 iexpmprodGrayStrategyConfig 配置项,grayBizCode 填写你的业务码。
Step 3: 在业务代码中调用:
@SofaReference
private GrayStrategyService grayStrategyService;
public void yourBusinessMethod() {
String userId = getCurrentUserId();
boolean isNewFlow = grayStrategyService.isPassGrayStrategy(
GrayBizCodeEnum.YOUR_BIZ_SCENE_CODE.name(),
userId,
GrayStrategyService.buildUidParamMap(userId),
false // 配置不存在时默认走老流程
);
if (isNewFlow) {
// 新流程
} else {
// 老流程
}
}
10.2 新增灰度模式
如果现有 7 种模式不满足需求,扩展步骤如下:
Step 1: 实现 GrayStrategyHandler 接口:
public class YourCustomHandler implements GrayStrategyHandler {
@Override
public boolean handle(GrayStrategyConfig config, String targetId,
Map<String, String> param) {
// 你的灰度判定逻辑
return true; // or false
}
}
Step 2: 在 GrayStrategyModeEnum 中添加枚举值:
YOUR_MODE("YOUR_MODE", "你的模式描述", new YourCustomHandler()),
Step 3: 在配置中心的 modeList 中使用 "YOUR_MODE" 即可。
10.3 参数构建速查
| 场景 | 构建方法 |
|---|---|
| 按 userId 灰度 | GrayStrategyService.buildUidParamMap(userId) |
| 按 instCode 灰度 | GrayStrategyService.buildInstCodeParamMap(instCode) |
| 按 label 灰度 | GrayStrategyService.buildLabelParamMap(label) |
| 按 bizScene 灰度 | GrayStrategyService.buildBizSceneParamMap(bizScene) |
| 按 loginId 灰度 | GrayStrategyService.buildLoginIdParamMap(loginId) |
| 按 salePlanCode 灰度 | GrayStrategyService.buildSalePlanCodeParamMap(salePlanCode) |
| 自定义维度 | GrayStrategyService.buildParamMap("yourKey", "yourValue") |
| 多维度组合 | 自行构建 Map 并 put 多个 key-value |
11. 最佳实践
11.1 命名规范
灰度业务码应清晰表达场景语义,推荐格式:{业务域}_{功能描述}_{灰度目的}
✅ SUPPLY_B2B_MEMBER_WITH_REGISTER_FROM (绑定会员指定 registerFrom)
✅ PORTAL_ONBOARD_STRUCTURE_CHANGE_ISNTCODE (门户入驻解耦-主体维度)
✅ MERCHANT_TRANSACTION_RISK_LIMIT (商户交易限制)
✅ ONBOARD_HK_Z05_SWITCH (香港商户切流到 Z05)
11.2 defaultResult 的选择
- 保守策略(推荐):传
false,配置不存在时走老流程。适用于新功能上线初期。 - 激进策略:传
true,配置不存在时走新流程。适用于老流程即将下线的场景。
11.3 日志可观测
每次灰度决策都有 digest 日志输出:
[GrayStrategyService-digest]bizCode=YOUR_BIZ_CODE,targetId=2088xxx,params={userId=2088xxx},isPassGrayStrategy=true.
利用这个日志可以进行线上灰度效果统计和问题排查。
11.4 切流节奏建议
1% → 观察 2-3 天 → 5% → 观察 2-3 天 → 10% → 30% → 50% → 80% → 100% → ALL_PASS
每次调整百分比只需修改配置中心的 cutPercentage 值,即时生效。
12. 类图总览
GrayStrategyService (接口)
│
└── GrayStrategyServiceImpl (决策引擎)
│
├── GrayStrategyConfig (配置模型)
│ bizCode / switchOn / modeList / ruleMap / cutPercentage
│
├── GrayStrategyModeEnum (策略路由)
│ ALL_PASS ────→ DefaultStrategyHandler
│ WHITE_LIST ──→ WhiteListStrategyHandler
│ BLACK_LIST ──→ BlackListStrategyHandler
│ UID_PERCENTAGE → PercentageStrategyHandler
│ └── ReferenceUidPercentageStrategyHandler
│ WHITE_LIST_ANY_MATCH_ENOUGH → AnyMatchEnoughWhiteListStrategyHandler
│ └── AnyMatchEnoughWhiteListAndPercentageStrategyHandler
│ WHITE_LIST_WITH_PERCENTAGE ──→ (同上)
│
└── GrayBizCodeEnum (业务码)
FIX_ALI_TRIP_SETTLE_CHANNEL
SUPPLY_B2B_MEMBER_WITH_REGISTER_FROM
PORTAL_ONBOARD_STRUCTURE_CHANGE_ISNTCODE
... (40+ 业务码)
更多推荐


所有评论(0)