3. 灰度策略设计:基于用户ID、基于IP、基于地域、基于用户属性(VIP/白名单)
灰度策略怎么选?说白了,就是决定「让谁先尝鲜」。
我见过不少团队,一上来就搞随机灰度,结果线上出了事故,连谁受影响都查不到。嗯,这里要敲黑板——灰度策略的核心不是技术实现,而是业务可控性。
3.1 基于用户ID:最常用的精准控制
这是我最推荐的方式。用户ID是天然的唯一标识,不会变,也不会重复。
具体怎么做?取用户ID的哈希值,对100取模。比如哈希值模100后落在0-4的,就是5%的灰度用户。
// 伪代码示例
function isInGray(userId, grayPercent) {
// 用MD5做哈希,分布更均匀
let hash = md5(userId.toString());
let mod = parseInt(hash.substring(0, 8), 16) % 100;
return mod < grayPercent;
}
我在项目中遇到过一个问题:用户反馈说「为什么我昨天在灰度里,今天不在了?」。原因很简单——灰度比例调整了。所以,如果你希望用户「一旦进入灰度就固定下来」,可以用用户ID + 功能标识做组合哈希。
3.2 基于IP:适合网络层面的灰度
基于IP的灰度,说白了就是按「来源」控制。比如只让公司内网IP访问新版本,或者只让某个城市的IP先体验。
但这里有个坑——NAT。公司几百号人可能共享一个公网IP。你开了10%的灰度,结果要么全进,要么全不进。
// IP灰度示例:取IP最后一段
function isInGrayByIp(clientIp, grayPercent) {
let segments = clientIp.split('.');
let lastSegment = parseInt(segments[3]);
return lastSegment % 100 < grayPercent;
}
基于IP还有一个好处——可以配合CDN或网关做灰度。不需要改代码,直接在Nginx层配规则就行。
3.3 基于地域:适合区域性发布
这个策略很直观。比如新功能先在上海上线,没问题再推到北京、深圳。
实现方式有两种:
- IP地理库:根据用户IP查归属地。我建议用MaxMind的GeoIP库,准确率还行。
- 用户资料中的地域字段:如果用户注册时填了城市,直接用这个字段更准。
我个人习惯用第二种。为什么?因为IP地理库有时候会把「北京联通」的用户定位到「天津」,这偏差就大了。
// 地域灰度示例
const GRAY_CITIES = ['上海', '杭州', '深圳'];
function isInGrayByRegion(user) {
// 优先用用户资料中的城市
if (user.city && GRAY_CITIES.includes(user.city)) {
return true;
}
// 降级:用IP查
let ipCity = geoIpLookup(user.ip);
return GRAY_CITIES.includes(ipCity);
}
3.4 基于用户属性:VIP/白名单
这是最「政治正确」的灰度策略。VIP用户先体验,白名单用户先验证。
你想想看,如果新功能有bug,VIP用户遇到了,那后果很严重。所以VIP灰度要谨慎——我一般只给「VIP中的VIP」开灰度,比如年消费10万以上的用户。
白名单就简单多了。内部员工、测试账号、核心合作伙伴,直接写死在配置中心里。
// 用户属性灰度示例
const VIP_THRESHOLD = 100000; // 年消费10万
const WHITE_LIST = ['user_001', 'user_002', 'test_admin'];
function isInGrayByAttribute(user) {
// 白名单优先
if (WHITE_LIST.includes(user.id)) {
return true;
}
// VIP用户:按等级灰度
if (user.vipLevel >= 5 && user.annualSpend > VIP_THRESHOLD) {
return true;
}
return false;
}
3.5 四种策略的对比与选择
| 策略 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
| 基于用户ID | 精准、稳定、可追溯 | 需要用户登录态 | 大部分业务场景 |
| 基于IP | 无需登录、网关层实现 | NAT问题、不够精准 | 网络层灰度、内测 |
| 基于地域 | 区域性控制、风险隔离 | 依赖地理库准确度 | 区域性发布、合规要求 |
| 基于用户属性 | 业务价值高、风险可控 | 规则复杂、维护成本高 | VIP体验、内部测试 |
实际项目中,我很少只用一种策略。通常是组合使用:
- 先基于用户属性,把白名单和VIP放进去
- 再基于地域,控制某个城市先上线
- 最后基于用户ID,按比例逐步放开
嗯,灰度策略设计这块,说白了就是「谁先上、谁后上、谁不上」。选对策略,能让你在出问题时快速定位、快速回滚。选错了,那就是给自己挖坑。