通过MSE提供的全链路灰度能力,您可以无需修改业务代码,实现全链路流量控制。本文介绍如何通过配置MSE全链路灰度功能,为Java微服务网关或者Spring Cloud应用这类入口应用实现全链路灰度。

使用限制

由于全链路灰度功能整合了标签路由功能,因此不推荐已经加入全链路流量控制的应用同时配置金丝雀发布、标签路由规则。

限制项 限制值 备注
Spring Cloud版本 Spring Cloud Edgware及以上版本。
Dubbo版本 2.5.3~2.7.8 Dubbo 3.0+版本支持当前处于灰度中,如有场景需求,请加入钉群(钉群号:34754806)联系技术支持。
客户端类型
  • Resttemplate
  • Spring Cloud OpenFeign
Java应用JDK版本 目前支持JDK 1.6、1.7、1.8版本应用接入 JDK 1.11版本当前处于灰度中,如有场景需求,请加入钉群(钉群号:34754806)联系技术支持。
负载均衡类型
  • Ribbon 2.0.x+
  • LoadBalancer 3.0.x+
Spring Cloud Gateway版本 Spring Cloud Gateway 2.1.0.RELEASE+
Spring Cloud Zuul版本 1.3.x
注册中心类型
  • Nacos
  • Eureka
  • ZooKeeper
微服务治理能力无关注册中心,可以是MSE托管注册中心,也可以是自建注册中心。

背景信息

在微服务场景中,当您部署的Spring Cloud应用或Dubbo应用存在升级版本时,由于应用间的调用是随机的,会导致无法将具有一定特征的流量路由到应用的目标版本。全链路流量控制功能将应用的相关版本隔离成一个独立的运行环境(即 泳道 ),通过设置泳道规则,将满足规则的请求流量路由到目标版本应用。

本文以电商架构中的下单场景为例,介绍Java微服务网关到微服务的全链路流控功能。假设应用的架构由Java微服务网关Zuul,以及后端的微服务架构(Spring Cloud)组成。后端调用链路有3个:购物车(A)、交易中心(B)和库存中心(C),可以通过客户端或者是HTML来访问后端服务,这些服务之间通过Nacos注册中心实现服务发现。

用户下单后,流量从Java微服务网关(Spring Cloud Gateway或者Spring Cloud Zuul)进来,调用交易中心,交易中心再调用商品中心,商品中心调用下游的库存中心。交易中心和商品中心各有两个新版本(1和2)在运行,需要对这两个新版本进行灰度验证。此时通过配置微服务网关的全链路灰度规则将满足特定流控规则的请求流量路由到新版本,其余流量全部路由到线上(正式)版本。泳道规则

术语说明

术语 说明
泳道 相同版本应用定义的一套隔离环境。只有满足了流控路由规则的请求流量才会路由到对应泳道里的打标应用。每条泳道,和一个标签相对应。泳道组里标签相同的多个应用节点,必定属于同一个泳道。一个应用可以属于多个泳道,一个泳道可以包含多个应用,应用和泳道是多对多的关系。
泳道组 泳道的集合。泳道组的作用主要是为了区分不同团队或不同场景。

适用场景

  • 入口应用为Java微服务网关(Spring Cloud Gateway/Spring Cloud Zuul)或者Spring Cloud应用。
  • 想要根据请求的Header、Cookie和Parameter等特征配置规则来实现全链路灰度。

准备工作

创建Kubernetes集群

具体创建操作,请参见创建Kubernetes托管版集群创建Kubernetes专有版集群

开启MSE微服务治理

  1. MSE微服务治理开通页面,开通微服务治理专业版。
    关于微服务治理的计费详情,请参见计费概述
  2. 安装MSE微服务治理组件。
    1. 登录容器服务控制台
    2. 在左侧导航栏,选择市场 > 应用市场,在搜索框中输入ack-onepilot,单击该组件。
    3. ack-onepilot页面右上方,单击一键部署,在创建面板中选择集群和命名空间,设置组件发布名称,然后单击下一步
      说明 推荐使用默认的命名空间ack-onepilot
    4. 参数配置页面,确认组件参数信息,然后单击确定
      安装完成后,在命名空间ack-onepilot中出现ack-onepilot应用,表示安装成功。
  3. 为应用开启微服务治理。
    1. 登录MSE治理中心控制台
    2. 在左侧导航栏,选择治理中心 > 运维中心 > K8s集群列表。在目标集群操作列,单击管理
    3. 集群详情页面,在目标命名空间操作列,单击开启微服务治理。然后单击确定

部署Demo应用程序

  1. 登录容器服务控制台
  2. 在左侧导航栏,选择集群,然后单击目标集群名称。
  3. 在左侧导航栏,选择工作负载 > 无状态
  4. 在页面上方,选择集群的命名空间,然后单击右上角的使用YAML创建资源
  5. 对模板进行相关配置,完成配置后单击创建
    本文示例中会部署A、B、C三个应用,其中A、B应用分别部署一个基线版本和一个灰度版本;部署一个Java微服务网关Zuul,并部署一个Nacos Server应用用于实现服务发现。部署所使用的YAML文件如下,您也可以在GitHub上获取对应的源代码。
部署所使用的YAML文件
# 部署 Nacos Server
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nacos-server
spec:
  selector:
    matchLabels:
      app: nacos-server
  template:
    metadata:
      labels:
        app: nacos-server
        msePilotAutoEnable: 'off'
    spec:
      containers:
      - env:
        - name: MODE
          value: "standalone"
        image: registry.cn-shanghai.aliyuncs.com/yizhan/nacos-server:latest
        name: nacos-server
        ports:
          - containerPort: 8848
---
apiVersion: v1
kind: Service
metadata:
  name: nacos-server
spec:
  type: ClusterIP
  selector:
    app: nacos-server
  ports:
    - name: http
      port: 8848
      targetPort: 8848

---
# 部署业务应用
apiVersion: apps/v1
kind: Deployment
metadata:
  name: spring-cloud-zuul
spec:
  selector:
    matchLabels:
      app: spring-cloud-zuul
  template:
    metadata:
      labels:
        app: spring-cloud-zuul
        msePilotCreateAppName: spring-cloud-zuul
        msePilotAutoEnable: 'on'
    spec:
      containers:
      - name: spring-cloud-zuul
        image: registry.cn-shanghai.aliyuncs.com/yizhan/spring-cloud-zuul:1.0.0
        imagePullPolicy: Always
        ports:
          - containerPort: 20000

---
apiVersion: v1
kind: Service
metadata:
  annotations:
    service.beta.kubernetes.io/alibaba-cloud-loadbalancer-spec: slb.s1.small
    service.beta.kubernetes.io/alicloud-loadbalancer-address-type: internet
  name: zuul-slb
spec:
  ports:
    - port: 80
      protocol: TCP
      targetPort: 20000
  selector:
    app: spring-cloud-zuul
  type: LoadBalancer

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: spring-cloud-a
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: 10
          periodSeconds: 30

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: spring-cloud-b
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: 10
          periodSeconds: 30

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: spring-cloud-c
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: 10
          periodSeconds: 30
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: spring-cloud-a-gray
spec:
  selector:
    matchLabels:
      app: spring-cloud-a-gray
  template:
    metadata:
      labels:
        app: spring-cloud-a-gray
        alicloud.service.tag: gray
        msePilotCreateAppName: spring-cloud-a
        msePilotAutoEnable: 'on'
    spec:
      containers:
      - name: spring-cloud-a-gray
        image: registry.cn-shanghai.aliyuncs.com/yizhan/spring-cloud-a:1.0.0
        imagePullPolicy: Always
        ports:
          - containerPort: 20001
        livenessProbe:
          tcpSocket:
            port: 20001
          initialDelaySeconds: 10
          periodSeconds: 30
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: spring-cloud-b-gray
spec:
  selector:
    matchLabels:
      app: spring-cloud-b-gray
  template:
    metadata:
      labels:
        app: spring-cloud-b-gray
        alicloud.service.tag: gray
        msePilotCreateAppName: spring-cloud-b
    spec:
      containers:
      - name: spring-cloud-b-gray
        image: registry.cn-shanghai.aliyuncs.com/yizhan/spring-cloud-b:1.0.0
        imagePullPolicy: Always
        ports:
          - containerPort: 20002
        livenessProbe:
          tcpSocket:
            port: 20002
          initialDelaySeconds: 10
          periodSeconds: 30

步骤一:创建泳道组

  1. 登录MSE治理中心控制台,并在顶部菜单栏选择地域。
  2. 在左侧导航栏,选择治理中心 > 全链路灰度
  3. 单击创建泳道组及泳道。如果您选择的微服务空间内已经创建过泳道组,则单击+创建泳道组
  4. 创建泳道组面板,设置泳道组相关参数,然后单击确定
    配置项 说明
    泳道组名称 自定义设置泳道组的名称。
    入口类型 目前支持Ingress及自建网关应用,以及Java服务网关(包含Spring Cloud微服务应用)
    入口应用 选择您的入口应用。
    泳道组涉及应用 选择您入口网关所涉及的所有相关服务。
    开启消息灰度 开启消息灰度会打开泳道组所有应用的消息灰度开关。
    消息灰度过滤侧 开启消息灰度后,此功能会展现。根据您的需要选择客户端过滤服务端过滤,推荐使用服务端过滤
    泳道组创建完成后,在全链路灰度页面的泳道组区域,可以查看您创建的泳道组。如需变更泳道组信息,单击编辑图标,可在页面自行修改相关信息。

步骤二:创建泳道

  1. 全链路灰度页面上方,选择和泳道组相同的地域,然后在底部单击点击创建第一个分流泳道。如果您选择的微服务空间内已经创建过泳道,则单击创建泳道
    说明 加入全链路流量控制的应用,将不再支持金丝雀发布、标签路由等功能。
  2. 创建泳道面板,设置流控泳道相关参数,然后单击确定
    配置项 说明
    泳道名称 自定义设置流控泳道的名称。支持大小写字母、数字、短划线(-)和下划线(_),长度不超过64个字符。
    配置应用标签
    • 配置方式:在容器ACK控制台中,在应用YAML的spec.template.metadata.labels下增加alicloud.service.tag:{tag}
    • 设置标签名:如“B-gray”,并为spec.template.metadata.labels增加如下两个key-value键值对。
      • msePilotCreateAppName:${AppName}
      • alicloud.service.tag:gray
    添加应用 完成配置应用标签后,下拉框中会出现相应的标签列表,选择对应的标签,则会自动添加相应的应用。
    路由规则 设置相应的路由规则条件。本文示例中设置的流量规则条件请求的Parmeter为name=xiaoming。要匹配的路径,可以多选。如果不填写的话,会匹配任意路径。
    • Path:选择需要匹配的路径,可以多选。如果不选择,会匹配任意路径。
    • 条件模式:路由条件之间的关系。
    • 条件列表:单击下方的+ 添加新的规则条件,新增规则条件。
    完成泳道创建后,在全链路灰度流量分配区域,可以查看泳道详情。
    • 操作列,选择开启,创建的泳道将会生效,即流量会按照泳道方式进行流转,满足规则的流量会优先流向标记有当前泳道对应标签的应用版本,如果没有对应标签的应用版本则流向未打标的应用版本。
    • 操作列,选择关闭,关闭创建的泳道,即该应用往后的流量会流向未打标的应用版本。
    • 单击图标图标,可以查看该泳道的流量比例。
    • 单击应用状态图标图标,可以设置该泳道上应用的状态。

步骤三:验证特征流量路由到目标应用

结果验证

  1. 登录容器服务控制台
  2. 在左侧导航栏,单击集群,然后单击目标集群名称。
  3. 在左侧导航栏,选择网络 > 服务
  4. 单击zuul-slb服务所对应的外部端点地址。
  5. 在服务调用页面输入/A/a?name=xiaoming,然后单击开始调用。全链路灰度功能已经生效。
    结果验证

查看打标应用的流量监控图

  1. 全链路灰度页面,单击目标泳道组页签。
  2. 泳道组涉及应用区域,单击目标应用名称,即可在右侧出现相应的QPS监控图。
    QPS监控图

查看所有应用监控图

您除了查看单个应用的监控图外,您还可以查看泳道组内所有应用的监控图。在QPS监控图右侧单击查看所有应用监控(流量逃逸观测),您可以查看该泳道所有应用的流量监控视图。您可以选择查看同一时刻调用的应用概览信息,也可以分析流量逃逸问题,判断逃逸对象。所有应用监控图