上个月我们组搞618大促前的最后一轮版本上线,差点因为流量切分的破事,把整个下单链路搞崩。
当时负责配置的后端小哥,盯着后台的切分规则看了三圈,觉得万无一失。
哪知道。
规则里漏了个条件,把全量钻石会员的请求都导去了新版本服务。新版本里藏了个优惠券计算的bug,用户点支付的时候,直接把应付金额算成了0.01元。等我们发现的时候,已经有两百多个用户付了款,客服的反馈消息直接弹满了值班群。
别上来就按标签占比切流量
很多刚接触灰度的朋友,上来就盯着配置页的流量占比滑块,拉到10%,觉得差不多就行。哪有这么省心。
你在配置页看到的“某类用户占比刚好10%”的预估,本质上就是个参考值。就像外卖平台给的预计送达时间,差个十几分钟都是常事。上次我们的小哥算的时候,只拉了静态的用户标签数据,没算到大促前一周运营拉新活动,刚好导入了一万多个新的钻石等级用户,实际切走的流量直接冲到了27%。真出问题的时候,这个占比的流量,足够把大盘的支付成功率拉低好几个百分点。
按固定用户标签切分的最大风险,就是你永远没法保证这部分流量的稳定性。你今天设的规则,可能明天因为产品改了用户等级的判定逻辑、运营搞了个专属活动,就把完全不相关的流量给卷进来了。

我们后来改规则的时候,直接把所有按标签切的配置都清了。谁知道哪个标签什么时候会变。
别把切分粒度搞的太粗
有些团队为了省事儿,直接按机房切流量。东边机房全走新版本,西边机房全走老版本。听起来好像两边的流量差不多,挺公平。
上次我们就吃过这个亏。
新版本的日志上报模块有内存泄漏,东边机房的实例跑了俩小时,内存直接冲到85%,整个机房的下单延迟从200ms涨到2s。监控告警弹了半屏,值班的同事手都抖了,切回老版本的时候点错了按钮,差点把两边的流量全导去新版本。
说穿了,这种按机房、按整个业务线切的方式,本质上就是把灰度当成了小范围全量。一旦新版本有问题,所有集中在这个范围里的用户全都会受影响,客诉是按堆来的。

合理的切分粒度,是要把风险摊到足够散的位置。我们现在用的规则很简单,给每个进来的请求生成一个随机traceId,尾号是1、2的请求,导去新版本服务。算下来刚好5%的流量,不管你是钻石会员还是新注册的用户,不管你在哪个城市,不管你用的是安卓还是iOS,被切到新版本的概率都是一样的。之前我们试过按用户ID哈希切,结果发现有些用户的请求因为带了不同的渠道参数,哈希出来的结果不一样,同一会话的请求一半走新版本一半走老版本,导致下单的时候报跨域错误。后来换成traceId尾号切,同一次会话的请求traceId是一样的,自然就会被导去同一个版本,再也没出过这类问题。就算新版本出了问题,影响的就是散落在各个渠道的5%用户,整体大盘的波动也就1%左右,根本不会触发集中的客诉。
切完流量别当甩手掌柜
很多团队的流程是,切完流量,等半小时看一眼整体错误率,没问题就直接全量。
真的。
谁踩谁知道。
上次我们切完新版本的流量,前20分钟所有大盘指标都正常,错误率跟老版本没差,延迟甚至还低了一点。结果到了第25分钟,突然有用户反馈说,下单成功之后根本看不到对应的订单记录。查了半天才发现,新版本的订单查询接口,对带“预售”标签的商品的查询逻辑有问题。这部分请求占总流量的比例才2%,前20分钟刚好碰到的请求少,问题没暴露,等流量跑了一会,这部分的请求量上来了,问题才炸出来。
这里有个非常实在的小技巧,切完流量之后,别光盯着整体的错误率、延迟这些大盘数据看。要把切到新版本的流量的核心业务转化漏斗单独拉出来,跟同时间段老版本的同链路数据做逐环节对比。比如从商品详情页到加购,到下单,到支付,到支付成功后的订单查询,每一步的转化率只要比老版本低1%以上,别等,直接把这部分流量切回去,别硬扛着等监控告警。
毕竟监控的告警阈值,一般都是按全量流量设的。10%的流量出问题,整体的错误率可能才涨0.3%,根本到不了告警线。等你收到告警的时候,已经有几千个用户碰到问题了。
说实话,我们之前总觉得灰度发布是个很复杂的技术活,要上复杂的流量治理框架,要搞服务网格的全链路灰度。真的踩过几次坑才发现,哪有那么多花里胡哨的东西。
最核心的就三点。
切的流量足够随机。
粒度足够散。
出问题的时候能10秒把流量切回去。
就够了。