日期:2026-08-27
网关每次升级模型版本,我们过去都是直接全量切。赌赢了皆大欢喜,赌输了全站受影响,回滚还要花时间。想只让一小撮流量先试新版本,技术上做不到,因为没有机制把"这一小撮"标出来并一路带过去。新版本一旦有隐藏 bug,只能等线上报错才发现,代价太大。那次全量切了一个有内存泄漏的版本,半个下午网关错误率飙升,客服群炸了,我们 rollback 花了二十分钟才稳住。
事后复盘,真正的痛点不是"切错了",而是"没法小步试错"。工业上早就有的灰度,在我们这儿因为没有染色能力,根本做不了。这件事让我们确定,灰度不是锦上添花,是发版的基本安全绳,没有它,每一次变更都是在赌。
我们给请求加了染色能力,在入口打上版本标,这个标随请求一路透传到下游,网关据此把染色流量路由到新版本模型,其余仍走稳定版。灰度比例可以调,先放一成,指标没问题再逐步放量。引流期间新版本和稳定版的延迟、错误率、答案质量并排对比,异常自动触发回滚。整个发版从"一把梭"变成了"先探后放",发布群里的气氛都轻松了,再没人半夜被叫起来救火。
为了让业务方配合,我们把引流看板做成谁发版谁先看,新版本的坏 case 直接挂在发布单上,责任人一目了然。稳定版也保留一份对照指标,避免"新版本好像还行"这种凭感觉的判断。
染色标透传是最坑的一步。我们第一版染色只打在入口,没管下游服务有没有把标继续带下去,结果灰度流量到了模型侧标识丢了,指标对比对不上,白灰了一场。后来统一了透传规范,每个中间件都必须原样往下传,不传就拒绝请求,才解决问题。灰度比例也不能拍脑袋,太小发现不了问题,太大风险又上来,我们按业务重要度分档,核心链路先放更低的量。
自动回滚的触发条件要稳,误报回滚比不回滚还烦,我们用多指标联合判断,单点抖动不触发。我们还踩过一个坑:最早回滚只看错误率,结果新版本错误率正常但答案质量悄悄下降,没触发,后来把 badcase 率也加进联合判断才兜住。
案例片段(已脱敏): 请求染色与灰度引流路由的核心配置如下:
yaml dye: header: x-route-tag pass_through: mandatory # 下游必须透传,否则拒绝 canary: ratio: 0.10 # 先放一成 step_up: [0.1, 0.3, 0.6, 1.0] rollback: on: [error_rate, p99_latency, badcase_rate] auto: true某次新版本错误率突增,灰度放量到三成时被自动回滚,稳定版零影响,全程无人手工介入。
每次灰度的结果我们都沉淀成发布档案,新版本引流期间的错误率、延迟、坏 case 全留痕,下次发类似版本直接对照。这个档案后来成了复盘利器,哪类变更容易在灰度阶段暴露问题,一眼能看出来,新人的发版培训也省了。灰度不只是保险绳,还是团队经验的容器,用好了比写文档管用。
染色命中率从第一版因透传缺失的约六成,提升到接近百分之百,灰度流量终于能对得准。灰度误差(误放到稳定版或漏染)降到千分之一以内。回滚时效从过去人工发现加操作的十几分钟,压到秒级自动触发。新版本坏 case 在灰度阶段就能拦下,再没出现过全量上线后大面积翻车。发版频次反而提高了,因为大家敢发了,平均每周的发版次数比全量切时代翻了一倍多。
网关发版绝不能一把梭,染色加灰度引流是把风险拆小的基本功,但染色标透传这件小事不搞定,后面全白费,我们就是被它坑过一次才长记性。灰度比例按业务分档,核心链路谨慎、边缘链路可以激进,一刀切反而束手束脚。自动回滚用多指标联合判断,单点抖动就回滚,运维会被你自己的告警逼疯,而且光看错误率不够,答案质量这种隐性退化也得算进去。说到底,灰度不是为了炫技,是给"不确定的变更"买一份可控的保险,保险越稳,团队越敢往前走,发版从负担变成日常。
发布纪律也跟着立起来了。以前谁都能半夜手痒全量切,现在流程强制走染色灰度,不灰度不让放量,违规操作在发布单上留痕。半年下来,因发版导致的线上事故从每月两三次降到零。规则把靠自觉换成了靠流程,团队睡觉都安稳了。
回滚演练我们也定期做,故意在灰度阶段注入一个错误率尖峰,验证自动回滚真能触发、且不影响稳定版。第一次演练时回滚慢了半拍,我们才发现联合判断的冷却时间设长了,调短之后才利落。演练的价值就是让保险绳在真出事时靠得住,而不是躺在配置里好看。
我们把灰度看板接到了发布流程里,谁发版谁先看引流对比,不用再等别人来问。把风险可视化,比写一百条规范都管用,人看到数字,自然就知道该放量还是该收。