流量染色灰度发布,能否告别线上事故一刀切?

摘要:大家好,我是小富~ 最近团队迭代频繁,连续几周都在做新功能上线,从测试环境验证到生产环境放量,全程谨小慎微没出一次故障,主要是用好了 Spring Cloud Gateway 的 流量染色 和 灰度发布。 很多同学面试时被问用过 Sprin
大家好,我是小富~ 最近团队迭代频繁,连续几周都在做新功能上线,从测试环境验证到生产环境放量,全程谨小慎微没出一次故障,主要是用好了 Spring Cloud Gateway 的 流量染色 和 灰度发布。 很多同学面试时被问用过 SpringCloud Gateway 吗?,只会说做限流、鉴权,但这些都是网关的基础操作。要想出去吹,得说用网关解决线上新版本平稳上线的问题。比如今天要分享的流量染色 + 灰度发布,就是我司每次上线必用的核心方案。 什么是流量染色?为什么需要它? 很多同学听流量染色觉得抽象,其实一句话就能说透:给请求打身份标签,让链路中所有服务都能认得出它。 比如我们做电商 APP 的新功能上线,想让 VIP 用户优先试用新版本,但普通用户继续用旧版本。怎么让订单、支付、库存这些下游服务知道当前请求是 VIP 用户的? 这时候就需要染色:请求进入网关时,判断用户身份是 VIP,就在请求头里加一个 X-Traffic-Tag: vip 的标识,这个过程就是流量染色。 后续的订单服务拿到请求,看到 X-Traffic-Tag: vip,就走新版本的订单逻辑;支付服务看到这个标签,就用新的支付接口;甚至日志系统看到这个标签,都会单独记录VIP 新版本的日志,单独处理这部分请求。 流量染色的核心价值在于,打破所有流量无差别处理的局限。有了染色标签,灰度发布、A/B 测试、环境隔离(比如测试流量不进生产库)才能落地。 什么是灰度发布? 搞懂了流量染色,灰度发布就好理解了,基于染色标签,让部分流量走新版本,逐步验证稳定性。 以前我们没做灰度时,上线都是一刀切:凌晨 2 点全量切换新版本,一旦出问题,所有用户都受影响,只能紧急回滚,既狼狈又容易丢数据。 现在用灰度发布,流程变成这样: 上线前:只让内部测试账号(染色标签 X-Traffic-Tag: test)走新版本,验证功能没问题; 上线初期:放 5% 的 VIP 用户(标签 vip)走新版本,观察日志和监控; 上线中期:没问题就扩大到 30%、50% 的 VIP 用户; 全量:确认稳定后,所有用户切换到新版本,灰度结束。 如果中间发现问题,比如 5% 的 VIP 用户反馈下单失败,直接把灰度规则关掉,所有流量切回旧版本,影响范围只有 5%,风险完全可控。 常见的灰度策略除了按用户标签,还有这些: 按比例:10% 流量走新版本(比如用用户 ID 取模,ID 尾号为 0 的用户); 按业务场景:只让 “新用户注册” 接口走新版本,老用户接口不变; 按设备:iOS 用户先切新版本,Android 用户后续再切(避免不同设备适配问题同时爆发)。 实现流量染色 + 灰度发布 接下来是重点:基于 SpringCloud Gateway,如何写代码实现这两个功能?整个流程分几步:请求染色→灰度路由→效果验证,所有代码都是生产环境可直接复用的。 项目依赖 首先确保引入 Gateway 核心依赖(Spring Boot 2.7.x + Spring Cloud Alibaba 2021.0.4.0 版本): <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-gateway</artifactId> </dependency> <!-- 用于服务发现(如果灰度路由到注册中心的服务) --> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency> 第一步:实现流量染色 流量染色的核心是拦截所有请求,按规则打标签,用 Gateway 的 GlobalFilter 就能实现,所有请求都会经过这个过滤器,我们在这里判断用户身份,注入染色标签。 比如我们的规则是: 如果请求参数里有 userType=vip,就给请求头加 X-Traffic-Tag: vip; 如果请求参数里有 userType=test,就加 X-Traffic-Tag: test; 其他请求默认加 X-Traffic-Tag: normal。
阅读全文