基于MSE云原生网关实现全链路灰度
通过MSE提供的全链路灰度能力,您无需修改业务代码,即可实现全链路流量控制。本文介绍如何通过配置MSE云原生网关实现端到端的全链路灰度。
背景信息
在微服务场景中,应用间的调用是随机的,当您部署的Spring Cloud应用或Dubbo应用存在升级版本时,会导致无法将具有一定特征的流量路由到应用的目标版本。全链路流量控制功能将应用的相关版本隔离成一个独立的运行环境(即泳道),通过设置泳道规则,将满足规则的请求流量路由到目标版本应用。
全链路灰度实现流程

使用限制
由于全链路灰度功能整合了标签路由功能(此处指的是MSE微服务治理的标签路由,与MSE云原生网关的标签路由无关),因此不推荐已经加入全链路流量控制的应用配置金丝雀发布和标签路由规则,
限制项 | 限制值 | 备注 |
注册中心类型 | MSE Nacos | 基于MSE云原生网关的全链路灰度目前暂只支持MSE Nacos。 |
MSE云原生网关版本 | 1.2.13及以上版本 | 1.2.13以下版本需要升级至最新版本。如何升级版本,请参见升级MSE云原生网关版本。 |
Spring Cloud版本 | Spring Cloud Edgware及以上版本 | 无。 |
Dubbo版本 | 2.5.3~2.7.8 | Dubbo 3.0及以上版本当前处于灰度中,如有场景需求,请提工单联系MSE技术支持。 |
客户端类型 | ResttemplateSpring Cloud OpenFeign | 无。 |
Java应用JDK版本 | 目前支持JDK 1.6、1.7、1.8版本应用接入 | JDK 1.11版本当前处于灰度中,如有场景需求,请提工单联系MSE技术支持。 |
负载均衡类型 |
| 无。 |
Spring Cloud Gateway版本 | Spring Cloud Gateway 2.1.0.RELEASE及以上版本 | 无。 |
Spring Cloud Zuul版本 | 1.3.x | 无。 |
场景示例
本文以电商架构中的下单场景为例,介绍从MSE云原生网关到微服务的全链路流控功能。假设应用的架构由MSE云原生网关以及后端的微服务架构(Spring Cloud)组成,后端调用链路有3个:交易中心(A)、商品中心(B)、库存中心(C),可以通过客户端或者是HTML来访问后端服务,这些服务之间通过MSE Nacos注册中心实现服务发现。
客户下单后流量从MSE云原生网关进来,调用交易中心(A),交易中心(A)再调用商品中心(B),商品中心(B)调用下游的库存中心(C)。总之,调用链路为:客户>MSE云原生网关>A>B>C。
随着业务不断迭代,新功能需要上线,涉及到应用A和应用C同时发布新版本。在新版本正式上线之前,需要同时对应用A和应用C进行灰度验证,确认无误后方可正式上线。
通过MSE云原生网关和MSE微服务治理提供的全链路灰度能力,您可以端到端构建从网关到多个后端服务的全链路灰度,控制具有一定特征的灰度流量始终路由到应用对应的灰度环境,满足您同时灰度验证多个服务的诉求。此外,在应用无目标灰度版本时,自动容灾到正式环境中。

名词解释
MSE云原生网关:MSE云原生网关是兼容K8s Ingress标准的下一代网关产品,支持ACK容器和Nacos等多种服务发现方式,支持多种认证登录方式快速构建安全防线。更多信息,请参见云原生网关概述。
泳道:为相同版本应用定义的一套隔离环境。只有满足了流控路由规则的请求流量才会路由到对应泳道里的打标应用。一个应用可以属于多个泳道,一个泳道可以包含多个应用,应用和泳道是多对多的关系。
泳道组:泳道的集合。泳道组的作用主要是为了区分不同团队或不同场景。
基线环境:未打标的应用属于基线环境,是其他环境的兜底环境。
准备工作
创建Kubernetes集群
具体创建操作,请参见创建Kubernetes专有版集群或创建Kubernetes托管版集群。
开启MSE微服务治理
请确保MSE Java Agent的版本2.8.0及以上,否则会影响业务运行。
在MSE微服务治理开通页面,开通微服务治理专业版。
将ACK微服务应用接入MSE治理中心,您可以选择您需要的方式实现应用接入。详细接入说明,请参见ACK微服务应用接入MSE治理中心
为ACK命名空间中的应用开启MSE微服务治理
登录MSE治理中心控制台,并在顶部菜单栏选择地域。
在左侧导航栏,选择治理中心 > 应用治理。
在应用列表页面,单击ACK应用接入。
在ACK应用接入对话框中,进行配置,配置完成后,单击确定。
配置项
说明
接入类型
选择命名空间接入。
集群类型
选择ACK集群或者ACK Serverless集群。
说明选择集群类型为ACK Serverless集群时,需要单击去授权链接对ACK Serverless集群进行授权。
集群名称/ID
选择接入MSE微服务治理的集群名称/ID,可通过关键词搜索。
ack-onepilot
显示ack-onepilot接入状态。如果您未安装ack-onepilot,单击ack-onepilot右侧的点击安装,安装完成后状态会显示为已安装。
说明该步骤接入的组件为ack-onepilot,您可以登录容器服务管理控制台进入目标集群,然后单击运维管理>组件管理查看详情。
集群命名空间
选择集群命名空间。
接入治理命名空间
选择接入治理命名空间。在对应命名空间下重新部署现有应用或新创建的应用,均会接入到MSE微服务治理中。关于命名空间的相关信息,请参见微服务命名空间管理。
为单个应用开启MSE微服务治理
登录MSE治理中心控制台,并在顶部菜单栏选择地域。
在左侧导航栏,选择治理中心 > 应用治理。
在应用列表页面,单击ACK应用接入。
在ACK应用接入对话框中,进行配置,配置完成后,单击确定。
配置项
说明
接入类型
选择单个应用接入。
集群类型
选择ACK集群或者ACK Serverless集群
集群名称/ID
选择接入MSE微服务治理的集群名称/ID,可通过关键词搜索。
ack-onepilot
显示ack-onepilot接入状态。如果您未安装ack-onepilot,单击ack-onepilot右侧的点击安装,安装完成后状态会显示为已安装。
说明该步骤接入的组件为ack-onepilot,您可以登录容器服务管理控制台进入目标集群,然后单击运维管理>组件管理查看详情。
接入步骤
按照接入步骤进行操作。
Step 1:进入集群工作负载-无状态应用页面,切换到应用的命名空间下。
Step 2:找到所接入的应用,点击「查看Yaml」。
Step 3:按以下格式编辑Labels,完成后点击「更新」。
spec: template: metadata: labels: # 填写“on”表示开启接入,需加上双引号 msePilotAutoEnable: "on" # 填写接入到的治理命名空间,值不存在可自动新建 mseNamespace: xl-mse-demo # 填写接入MSE的实际应用名称,需加上双引号 msePilotCreateAppName: "your-deployment-name"
创建MSE Nacos
具体创建操作,请参见创建Nacos引擎。
创建MSE云原生网关并关联MSE Nacos
MSE云原生网关与MSE Nacos需处于同一VPC。
关于创建网关的具体操作步骤,请参见创建MSE云原生网关。
关联已创建的MSE Nacos。具体操作,请参见新建服务来源。
步骤一:搭建业务应用的基线环境
步骤1:部署后端业务应用的基线版本
- 登录容器服务控制台。
- 在左侧导航栏,单击集群,然后单击目标集群名称。
- 在左侧导航栏,选择 。
- 在页面上方,选择集群的命名空间,然后单击右上角的使用YAML创建资源。
复制以下YAML文件内容,部署A、B、C三个应用的基线版本。
说明代码中的{nacos server address}需要替换成用户MSE Nacos的内网域名,同时需要去掉大括号
{}
。# 应用A的基线版本 apiVersion: apps/v1 kind: Deployment metadata: name: spring-cloud-a namespace: default spec: selector: matchLabels: app: spring-cloud-a template: metadata: labels: app: spring-cloud-a msePilotCreateAppName: spring-cloud-a msePilotAutoEnable: 'on' spec: containers: - name: spring-cloud-a image: registry.cn-shanghai.aliyuncs.com/yizhan/spring-cloud-a:1.0.0 imagePullPolicy: Always ports: - containerPort: 20001 livenessProbe: tcpSocket: port: 20001 initialDelaySeconds: 30 periodSeconds: 60 env: - name: spring.cloud.nacos.discovery.server-addr value: {nacos server address} - name: dubbo.registry.address value: 'nacos://{nacos server address}:8848' --- # 应用B的基线版本 apiVersion: apps/v1 kind: Deployment metadata: name: spring-cloud-b namespace: default spec: selector: matchLabels: app: spring-cloud-b template: metadata: labels: app: spring-cloud-b msePilotCreateAppName: spring-cloud-b msePilotAutoEnable: 'on' spec: containers: - name: spring-cloud-b image: registry.cn-shanghai.aliyuncs.com/yizhan/spring-cloud-b:1.0.0 imagePullPolicy: Always ports: - containerPort: 20002 livenessProbe: tcpSocket: port: 20002 initialDelaySeconds: 30 periodSeconds: 60 env: - name: spring.cloud.nacos.discovery.server-addr value: {nacos server address} - name: dubbo.registry.address value: 'nacos://{nacos server address}:8848' --- # 应用C的基线版本 apiVersion: apps/v1 kind: Deployment metadata: name: spring-cloud-c namespace: default spec: selector: matchLabels: app: spring-cloud-c template: metadata: labels: app: spring-cloud-c msePilotCreateAppName: spring-cloud-c msePilotAutoEnable: 'on' spec: containers: - name: spring-cloud-c image: registry.cn-shanghai.aliyuncs.com/yizhan/spring-cloud-c:1.0.0 imagePullPolicy: Always ports: - containerPort: 20003 livenessProbe: tcpSocket: port: 20003 initialDelaySeconds: 30 periodSeconds: 60 env: - name: spring.cloud.nacos.discovery.server-addr value: {nacos server address} - name: dubbo.registry.address value: 'nacos://{nacos server address}:8848'
步骤2:通过MSE云原生网关暴露应用A
情况一:新服务
如果您未在云原生网关上添加过应用A,可通过如下操作暴露应用A。
登录MSE管理控制台,在服务列表页面创建服务,配置如下。
服务来源:选择MSE Nacos。
命名空间:选择public。
选择服务:选择sc-A。
关于如何创建服务,请参见添加服务。
在服务列表页面的操作列,单击服务sc-A的策略配置。
查看sc-A的服务版本配置是否满足如下条件:
版本名称为base。
标签名为opensergo.io/canary。
标签值为空。
正常情况下,云原生网关默认为导入的Nacos的服务添加以上base版本,且base版本的实例数大于0。
在路由配置页面,单击创建路由,为服务sc-A创建路由完成对外暴露。
在请求信息页面,配置路由名称和关联域名,匹配规则选择前缀匹配,其他配置选择默认即可。
在目标服务页面,配置如下:
目标服务选择标签路由。
服务选择sc-A,服务的版本选择base。
勾选设置fallback服务,并将其版本设置为不限制,使sc-A达到高可用的目的。
情况二:线上已有服务
如果您的实际场景是针对已导入的服务,可通过如下操作暴露应用A。
在服务列表页面的操作列,单击目标服务的策略配置,查看服务信息。
正常情况下,该服务不存在版本名称为base,标签名为opensergo.io/canary,标签值为空的服务版本。
重新部署服务A。
在服务详情页面的服务版本区域,单击添加新版本,配置如下参数,然后单击操作列的
图标保存设置。最后确认base版本的实例数是否大于0。
版本名称设置为base。
标签名设置为opensergo.io/canary。
标签值为空。
在路由配置页面,编辑已有的路由,用于暴露sc-A服务。
在请求信息页面,匹配规则选择前缀匹配,其他配置选择默即可。
在目标服务页面,配置如下参数:
目标服务选择标签路由。
服务选择sc-A,服务的版本选择base。
勾选设置fallback服务,并将其版本设置为不限制,使sc-A达到高可用的目的。
步骤3:测试基线版本流量
登录MSE网关管理控制台,并在顶部菜单栏选择地域。
在左侧导航栏,选择云原生网关 > 网关列表,单击目标网关名称。
在左侧导航栏,单击基本概览。
在网关入口页签,查看SLB的入口地址(ip)。
用curl命令,测试基线版本流量,发现流量经过了A、B和C的基线版本。如下所示:
# 测试命令 curl x.x.1.1/a # 测试结果 A[10.0.3.178][config=base] -> B[10.0.3.195] -> C[10.0.3.201]%
如测试结果所示,B和C输出结果的应用名后面没有版本,则代表访问对应应用的基线版本。
步骤二:搭建业务应用的灰度环境
如果业务应用要发布新功能,新功能要求应用A和应用C同时发版,这时就需要借助全链路灰度来同时验证不同应用的灰度版本。
步骤1:部署后端业务应用的灰度版本
- 登录容器服务控制台。
- 在左侧导航栏,单击集群,然后单击目标集群名称。
- 在左侧导航栏,选择 。
- 在页面上方,选择集群的命名空间,然后单击右上角的使用YAML创建资源。
复制以下YAML文件内容,部署A、C两个应用的灰度版本。
说明代码中的{nacos server address}需要替换成您MSE Nacos的内网域名,同时需要去掉大括号
{}
。# 应用A的灰度版本 apiVersion: apps/v1 kind: Deployment metadata: name: spring-cloud-a-gray namespace: default spec: selector: matchLabels: app: spring-cloud-a-gray template: metadata: labels: alicloud.service.tag: gray app: spring-cloud-a-gray msePilotCreateAppName: spring-cloud-a msePilotAutoEnable: 'on' spec: containers: - name: spring-cloud-a image: registry.cn-shanghai.aliyuncs.com/yizhan/spring-cloud-a:1.0.0 imagePullPolicy: Always ports: - containerPort: 20001 livenessProbe: tcpSocket: port: 20001 initialDelaySeconds: 30 periodSeconds: 60 env: - name: spring.cloud.nacos.discovery.server-addr value: {nacos server address} - name: dubbo.registry.address value: 'nacos://{nacos server address}:8848' --- # 应用C的灰度版本 apiVersion: apps/v1 kind: Deployment metadata: name: spring-cloud-c-gray namespace: default spec: selector: matchLabels: app: spring-cloud-c-gray template: metadata: labels: alicloud.service.tag: gray app: spring-cloud-c-gray msePilotCreateAppName: spring-cloud-c msePilotAutoEnable: 'on' spec: containers: - name: spring-cloud-c image: registry.cn-shanghai.aliyuncs.com/yizhan/spring-cloud-c:1.0.0 imagePullPolicy: Always ports: - containerPort: 20003 livenessProbe: tcpSocket: port: 20003 initialDelaySeconds: 30 periodSeconds: 60 env: - name: spring.cloud.nacos.discovery.server-addr value: {nacos server address} - name: dubbo.registry.address value: 'nacos://{nacos server address}:8848'
步骤2:创建灰度环境泳道
登录MSE治理中心控制台,并在顶部菜单栏选择地域。
在左侧导航栏,选择 。
单击创建泳道组及泳道。如果您选择的微服务空间内已经创建过泳道组,则单击创建泳道组。
在创建泳道组面板,单击+ 创建泳道组,在创建泳道组页面,设置如下相关配置,然后单击确定。
配置项
说明
泳道组名称
自定义泳道组的名称。
入口类型
选择MSE 云原生网关。
泳道组流量入口
选择目标云原生网关。
泳道组涉及应用
选择spring-cloud-a、spring-cloud-b和spring-cloud-c。
泳道组创建完成后,在全链路灰度页面的泳道组区域,可以查看您创建的泳道组。如需变更泳道组信息,单击
图标,可在页面自行修改相关信息。
在全链路灰度页面底部,单击点击创建第一个分流泳道。如果您选择的微服务空间内已经创建过泳道,则单击创建泳道。
在创建泳道面板,设置流控泳道相关配置,然后单击确定。
配置项
说明
添加应用
选择泳道标签后,会自动生成泳道名称并添加相应的应用。
路由规则
设置相应的路由规则条件。
选择已在网关创建的基线路由:选择在步骤一创建的基线路由
test
。条件模式:路由条件之间的关系。
条件列表:单击下方的+添加新的规则条件,新增规则条件。
本示例灰度条件配置如下:
参数类型:Header。
参数:canary。
条件:精确匹配。
值:gray。
完成泳道创建后,在全链路灰度的流量分配区域,可以查看泳道详情,还可以进行如下操作。
在操作列,选择开启,创建的泳道将会生效,即流量会按照泳道方式进行流转,满足规则的流量会优先流向标记有当前泳道对应标签的应用版本,如果没有对应标签的应用版本则流向未打标的应用版本。
在操作列,选择关闭,关闭创建的泳道,即该应用往后的流量会流向未打标的应用版本。
单击
图标,可以查看该泳道的流量比例。
单击
图标,可以设置该泳道上应用的状态。
步骤3:测试灰度版本流量
使用curl命令测试灰度流量。
# 测试命令
curl -H "canary: gray" x.x.x.x/a
# 测试结果
Agray[10.0.3.177][config=base] -> B[10.0.3.195] -> Cgray[10.0.3.180]
如测试结果所示,流量经过了A、C的灰度环境,由于B没有gray环境,所以流量自动容灾到基线版本。
(可选)步骤三:可观测
若应用出现异常,您可以通过MSE提供的可观测能力查看异常数据,帮助您快速定位问题。
云原生网关可观测
在MSE云原生网关的服务列表页面,单击目标服务的策略配置,在基础监控区域查看服务各个版本的流量情况。

QPS:该应用各个版本的QPS数据。
Errors:该应用各个版本的出错请求数。
RT(ms):该应用各个版本的请求响应耗时。
微服务治理可观测
在MSE微服务治理的全链路灰度页面,单击目标应用,在QPS监控图(总)区域,可查看对应泳道基线版本和灰度版本的流量情况。

总数:该应用总的QPS。
异常QPS:该应用出错的请求数。
gray:该应用gray版本的QPS。