通过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.8Dubbo 3.0及以上版本当前处于灰度中,如有场景需求,请提工单联系MSE技术支持。
客户端类型ResttemplateSpring Cloud OpenFeign无。
Java应用JDK版本目前支持JDK 1.6、1.7、1.8版本应用接入JDK 1.11版本当前处于灰度中,如有场景需求,请提工单联系MSE技术支持。
负载均衡类型
  • Ribbon 2.0.x及以上版本
  • LoadBalancer 3.0.x及以上版本
无。
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及以上,否则会影响业务运行。
  1. MSE微服务治理开通页面,开通微服务治理专业版。
    关于微服务治理的计费详情,请参见计费概述
  2. 安装MSE微服务治理组件。
    1. 登录容器服务控制台
    2. 在左侧导航栏,选择市场 > 应用市场,在搜索框中输入ack-onepilot,单击该组件。
    3. ack-onepilot页面右上方,单击一键部署,在创建页面,选择集群和命名空间,设置组件发布名称,单击下一步,然后单击确定
      说明 建议使用默认的命名空间ack-onepilot
      安装完成后,在命名空间ack-onepilot中出现ack-onepilot应用,表示安装成功。
  3. 为应用开启微服务治理。
    1. 登录MSE治理中心控制台
    2. 在左侧导航栏,选择治理中心 > 运维中心 > K8s集群列表。在目标集群操作列,单击管理
    3. 集群详情页面,在目标命名空间操作列,单击开启微服务治理。然后单击确定

创建MSE Nacos

具体创建操作,请参见创建Nacos引擎

创建MSE云原生网关并关联MSE Nacos

说明 MSE云原生网关与MSE Nacos需处于同一VPC。

步骤一:搭建业务应用的基线环境

步骤1:部署后端业务应用的基线版本

  1. 登录容器服务控制台
  2. 在左侧导航栏,单击集群,然后单击目标集群名称。
  3. 在左侧导航栏,选择工作负载 > 无状态
  4. 在页面上方,选择集群的命名空间,然后单击右上角的使用YAML创建资源
  5. 复制以下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}
    ---
    # 应用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。

  1. 登录MSE管理控制台,在来源管理页面创建服务,配置如下。
    • 服务来源:选择MSE Nacos
    • 命名空间:选择public
    • 服务:选择sc-A
    关于如何创建服务,请参见添加服务
  2. 服务列表页面的操作列,单击服务sc-A策略配置
    查看sc-A服务版本配置是否满足如下条件:
    • 版本名称base
    • 标签名opensergo.io/canary
    • 标签值为空。
    sc-a

    正常情况下,云原生网关默认为导入的Nacos的服务添加以上base版本,且base版本的实例数大于0。

    如果base版本中实例数显示为0,说明您安装的MSE Java Agent版本太低。请卸载原有的ack-onepliot,重新安装ack-onepliot,并确保ack-onepliot的版本为2.8.0及以上,然后重新部署应用A,部署完毕之后确认实例数是否大于0。

  3. 路由配置页面,为服务sc-A创建路由完成对外暴露。
    • 请求信息页面,配置路由名称关联域名匹配规则选择前缀匹配,其他配置选择默认即可。请求信息
    • 目标服务页面,配置如下:
      • 目标服务选择标签路由
      • 服务选择sc-A,服务的版本选择base
      • 勾选设置fallback服务,并将其版本设置为不限制,使sc-A达到高可用的目的。
      目标服务

情况二:线上已有服务

如果您的实际场景是针对已导入的服务,可通过如下操作暴露应用A。

  1. 服务列表页面的操作列,单击目标服务的策略配置,查看服务信息。
    正常情况下,该服务不存在版本名称为base,标签名为opensergo.io/canary,标签值为空的服务版本。
  2. 安装ack-onepliot,并确保ack-onepliot的版本为2.8.0及以上,然后重新部署服务A。
    关于如何安装ack-onepliot,请参见安装MSE服务治理组件
  3. 在服务详情页面的服务版本区域,单击添加新版本,配置如下参数,然后单击操作列的对勾图标保存设置。最后确认base版本的实例数是否大于0。
    • 版本名称设置为base
    • 标签名设置为opensergo.io/canary
    • 标签值为空。
  4. 路由配置页面,编辑已有的路由,用于暴露sc-A服务。
    • 请求信息页面,匹配规则选择前缀匹配,其他配置选择默即可。请求信息
    • 目标服务页面,配置如下参数:
      • 目标服务选择标签路由
      • 服务选择sc-A,服务的版本选择base
      • 勾选设置fallback服务,并将其版本设置为不限制,使sc-A达到高可用的目的。
      目标服务

步骤3:测试基线版本流量

  1. 登录MSE网关管理控制台,并在顶部菜单栏选择地域。
  2. 在左侧导航栏,选择云原生网关 > 网关列表,单击目标网关名称。
  3. 在左侧导航栏,单击基本概览
  4. 网关入口页签,查看SLB的入口地址(ip)
  5. 用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:部署后端业务应用的灰度版本

  1. 登录容器服务控制台
  2. 在左侧导航栏,单击集群,然后单击目标集群名称。
  3. 在左侧导航栏,选择工作负载 > 无状态
  4. 在页面上方,选择集群的命名空间,然后单击右上角的使用YAML创建资源
  5. 复制以下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}
    ---
    # 应用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:创建灰度环境泳道

  1. 登录MSE治理中心控制台,并在顶部菜单栏选择地域。
  2. 在左侧导航栏,选择治理中心 > 全链路灰度
  3. 单击创建泳道组及泳道。如果您选择的微服务空间内已经创建过泳道组,则单击+创建泳道组
  4. 创建泳道组面板,单击+ 创建泳道组,在创建泳道组页面,设置如下相关配置,然后单击确定
    配置项说明
    泳道组名称自定义泳道组的名称。
    入口类型选择MSE云原生网关
    入口应用选择目标云原生网关。
    泳道组涉及应用选择spring-cloud-aspring-cloud-bspring-cloud-c
    创建泳道组
    泳道组创建完成后,在全链路灰度页面的泳道组区域,可以查看您创建的泳道组。如需变更泳道组信息,单击编辑图标,可在页面自行修改相关信息。
  5. 全链路灰度页面底部,单击点击创建第一个分流泳道。如果您选择的微服务空间内已经创建过泳道,则单击创建泳道
  6. 创建泳道面板,设置流控泳道相关配置,然后单击确定
    配置项说明
    泳道名称自定义设置流控泳道的名称。本示例将泳道名称设置为gray
    配置应用标签配置方式:登录容器服务控制台,在应用YAML的spec.template.metadata.labels下增加alicloud.service.tag:{tag}

    例如,如果您需要设置gray标签,请在应用YAML的spec.template.metadata.labels下增加alicloud.service.tag: gray

    添加应用完成配置应用标签后,下拉框中会出现相应的标签列表,选择对应的标签,则会自动添加相应的应用。
    路由规则设置相应的路由规则条件。
    • 选择已在网关创建的基线路由:选择在步骤一创建的基线路由test
    • 条件模式:路由条件之间的关系。
    • 条件列表:单击下方的+ 添加新的规则条件,新增规则条件。
      本示例设置灰度条件为:请求Header名为canary,Header值为gray。配置如下:
      • 参数类型: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:该应用各个版本的请求响应耗时。
微服务治理可观测在MSE微服务治理的全链路灰度页面,单击目标应用,在QPS监控图(总)区域,可查看对应泳道基线版本和灰度版本的流量情况。应用监控
  • 总数:该应用总的QPS。
  • 异常QPS:该应用出错的请求数。
  • gray:该应用gray版本的QPS。