【阿里云实战】基于云原生API网关实现端到端全链路灰度

发布时间:2026/8/28 16:52:52
【阿里云实战】基于云原生API网关实现端到端全链路灰度 文章目录1.背景2.前提条件3.架构原理4. 操作步骤4.1 在 ACK 部署前端基线与灰度版本4.2 创建网关服务与前端路由4.3 配置 frontend-gray 插件(含前后端联动参数)4.4 部署后端微服务并接入 MSE 治理4.5 通过网关暴露后端入口应用4.6 创建泳道组与泳道5. 结果验证5.1 前端灰度验证5.2 后端全链路灰度验证5.3 前后端联动(原理说明)6. 常见问题6.1 灰度版本为什么不是实时生效?6.2 前端部署在 OSS/CDN 时如何配置?6.3 链路上某个服务没有灰度版本会怎样?6.4 放量建议6.5 转正建议6.6 回滚建议1.背景在微服务架构下,一次业务请求往往要经过网关和多个后端服务的调用链。当前端应用或链路中的部分服务发布新版本时,如果直接全量上线,一旦出现缺陷,爆炸半径就是全部用户。所以在微服务架构中,前端与后端通常独立部署和迭代。而为了安全地发布新版本,我们需要实现端到端的全链路灰度,减少发版故障。2.前提条件已经创建ACK集群,并且在ACK已经部署好前端应用与后端应用(basegray);开通云原生API网关,并且安装前端灰度frontend-gray插件;开通微服务治理中心,并且将后端服务接入治理中心;3.架构原理前端灰度:前端灰度 frontend-gray 插件从请求中提取用户唯一标识(grayKey,通常取自 Cookie 中的 userid),与 rules 中定义的灰度规则匹配:规则支持用户 ID 白名单(grayKeyValue)、用户分类标签(grayTagKey/grayTagValue)两种精确匹配方式,也支持在 grayDeployments 上配置 weight 做按比例灰度。命中任一规则即使用该规则同名(name 关联)的 grayDeployment,全部未命中则由 baseDeployment 兜底。在前端应用直接部署于 ACK(非 OSS/CDN)的形态下,插件对命中灰度的请求打上 x-higress-tag 请求头(取值即 grayDeployments[].version,如 gray),网关上预先创建的灰度路由以该 Header 为匹配条件,把请求转发到灰度前端 Service;未命中的请求落入基线路由。基线与灰度因此是两套长期共存的 Deployment + Service,互不覆盖。后端全链路灰度:后端采用 MSE 微服务治理的全链路灰度能力。接入 MSE 治理的 ACK 应用(通过 ack-onepilot 自动注入 Java 探针,业务代码零改造)中,未打标的实例属于基线环境,打了 alicloud.service.tag: gray 标签的灰度 Deployment 属于灰度环境。在 MSE 治理中心创建泳道组时,入口类型选择"云原生API网关"并指定网关实例,圈入调用链涉及的全部应用;再创建标签为 gray 的泳道,灰度模式选择"按内容灰度",条件设为 Header x-mse-tag == gray。网关把流量染色后,探针会在 Spring Cloud / Dubbo 等框架的调用上下文中自动携带标签向下游传递,每一跳都做"有灰度实例则优先灰度"的路由判定。当链路上某个服务没有部署灰度版本时(例如只有 A、C 发新版,B 未发),该跳流量自动回落到基线实例,保证调用链完整不中断——即"泳道隔离 + 基线兜底"模型。这正是全链路灰度相对单点灰度的本质价值:只需为真正变更的服务部署灰度版本,其余服务共享基线。前后端联动:前端灰度与后端全链路灰度的衔接,依靠 frontend-gray 插件 grayDeployments 中的 backendVersion 参数完成,这是全方案唯一的联动桥梁:配置 backendVersion 后,插件会自动为灰度用户页面发起的 XHR/Fetch 请求(即 API 调用)添加请求头 x-mse-tag: {backendVersion}(头名称可由 backendGrayTag 自定义,默认即 x-mse-tag),同时把 ${backendGrayTag}:{backendVersion} 写入 Cookie 持久化。前端代码无需任何改造,灰度用户的 API 流量天然携带后端灰度标识;后端 MSE 泳道规则只需以同一个 Header 作为匹配条件,即可接住这股流量。整个链路的流量走向如下:用户请求到达云原生 API 网关。前端灰度插件(frontend-gray) 解析请求(如检查 Cookie 中的userid)。流量分发:前端:插件根据规则识别灰度流量,未命中灰度的用户走 Base 路由访问基线前端,命中灰度的用户被打上 x-higress-tag 标识走 Gray 路由访问灰度前端。后端联动:插件在转发给后端的请求中注入灰度标识 Header(默认为x-mse-tag),值为灰度版本号。MSE 微服务治理:后端服务接收到带有灰度标识的请求,MSE 泳道规则识别,将流量路由到对应的后端灰度泳道;若无灰度实例,则自动回落至基线环境。4. 操作步骤4.1 在 ACK 部署前端基线与灰度版本前端以两套 Deployment + Service 长期共存:基线承接全部未命中流量,灰度仅承接灰度流量。镜像按版本独立构建、互不覆盖。# frontend-base.yaml —— 前端基线版本 apiVersion: apps/v1 kind: Deployment metadata: name: frontend namespace: default spec: replicas: 1 selector: matchLabels: app: frontend template: metadata: labels: app: frontend spec: containers: - image: 'registry.cn-hangzhou.aliyuncs.com/mse-demo-hz/user-gray:base' imagePullPolicy: Always name: frontend resources: {} --- apiVersion: v1 kind: Service metadata: name: frontend-base-svc namespace: default spec: ports: - port: 80 protocol: TCP targetPort: 80 selector: app: frontend type: ClusterIP # frontend-gray.yaml —— 前端灰度版本 apiVersion: apps/v1 kind: Deployment metadata: name: frontend-gray namespace: default spec: replicas: 1 selector: matchLabels: app: frontend-gray template: metadata: labels: app: frontend-gray spec: containers: - image: 'registry.cn-hangzhou.aliyuncs.com/mse-demo-hz/user-gray:gray' imagePullPolicy: Always name: frontend-gray resources: {} --- apiVersion: v1 kind: Service metadata: name: frontend-gray-svc namespace: default spec: ports: - port: 80 p