全部產品
Search
文件中心

Microservices Engine:基於MSE Ingress的全鏈路灰階

更新時間:Jul 30, 2025

通過MSE Ingress網關提供的全鏈路灰階能力,您可以在不需要修改任何業務代碼的情況下,實現全鏈路流量控制。本文介紹如何通過MSE Ingress網關實現全鏈路灰階功能。

前提條件

使用限制

由於全鏈路灰階功能整合了標籤路由功能,因此不推薦已經加入全鏈路流量控制的應用配置金絲雀發布和標籤路由規則。

全鏈路灰階能力支援的Java版本及架構詳見微服務治理支援的Java架構

背景資訊

在微服務情境中,當您部署的Spring Cloud應用或Dubbo應用存在升級版本時,由於應用之間的調用是隨機的,會導致無法將具有一定特徵的流量路由到應用的目標版本。全鏈路流量控制功能將應用的相關版本隔離成一個獨立的運行環境(即泳道),通過設定Ingress路由規則,將滿足規則的請求流量路由到目標版本應用。

全鏈路灰階情境

本文以電商架構中的下單情境為例,介紹從MSE Ingress網關到微服務的全鏈路流控功能。假設應用的架構由MSE Ingress網關以及後端的微服務架構(Spring Cloud)組成,後端調用鏈路有3個:交易中心(A)、商品中心(B)和庫存中心(C),可以通過用戶端或者是HTML來訪問後端服務,這些服務之間通過Nacos註冊中心實現服務發現。

客戶下單後流量從MSE Ingress網關進入,先調用交易中心(A),然後交易中心(A)再調用商品中心(B),最後商品中心(B)再調用下遊的庫存中心(C)。調用鏈路從左至右依次為:客戶->MSE Ingress->A->B->C。

隨著業務不斷迭代,功能也不斷更新。在新版本正式上線之前,需要同時對應用A和應用C進行灰階驗證,確認無誤後方可正式上線。新功能上線過程中,涉及到應用A和應用C同時發布新版本。通過MSE Ingress網關和MSE微服務治理提供的全鏈路灰階能力,您可以端到端的構建從網關到多個後端服務的全鏈路灰階,控制具有一定特徵的灰階流量始終路由到應用對應的灰階環境,滿足您同時灰階驗證多個服務的訴求。此外,在應用無目標灰階版本時,自動容災到正式環境中。

全鏈路灰階情境

名詞解釋

  • 泳道

    為相同版本應用定義的一套隔離環境。只有滿足了流控路由規則的請求流量才會路由到對應泳道裡的打標應用。一個應用可以屬於多個泳道,一個泳道可以包含多個應用,應用和泳道是多對多的關係。

  • 泳道組

    泳道的集合。泳道組的作用主要是為了區分不同團隊或不同情境。

  • MSE Ingress網關

    MSE Ingress網關是在MSE雲原生網關基礎上提供的Ingress流量管理方式,相容Nginx Ingress以及超50種Nginx Ingress註解,支援多服務版本同時灰階發布。同時,靈活的服務治理能力以及全方位的安全防護保障,可以滿足大規模雲原生分布式應用的流量治理訴求。

準備工作

開啟MSE微服務治理

  1. 開通微服務治理專業版。

    具體操作,請參見開通MSE微服務治理

  2. 為應用開啟微服務治理。

    1. 登入MSE治理中心控制台

    2. 在左側導覽列,選擇治理中心 > 營運中心 > K8s叢集列表。在目的地組群操作列,單擊管理

    3. 叢集詳情頁面,在目標命名空間操作列,單擊開啟微服務治理。然後單擊確定

部署Demo應用程式

  1. 登入Container Service管理主控台

  2. 在控制台左側導覽列,單擊叢集列表

  3. 叢集列表頁面,單擊目的地組群名稱或者目的地組群右側操作列下的詳情

  4. 在叢集管理頁左側導覽列,選擇工作負載 > 無狀態

  5. 無狀態頁面,選擇命名空間,然後單擊使用YAML建立資源

  6. 對模板進行相關配置,完成配置後單擊建立

    本文樣本中部署一個Nacos Server應用,用於實現服務發現,部署A、B、C三個應用。其中A和C應用分別部署一個基準版本和一個灰階版本,B應用部署一個基準版本。

    部署Nacos Server應用。

    展開查看YAML檔案

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: nacos-server
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: nacos-server
      template:
        metadata:
          labels:
            app: nacos-server
        spec:
          containers:
          - env:
            - name: MODE
              value: standalone
            image: registry.cn-hangzhou.aliyuncs.com/mse-governance-demo/nacos-server:v2.1.2
            imagePullPolicy: Always
            name: nacos-server
          dnsPolicy: ClusterFirst
          restartPolicy: Always
    
    # Nacos Server Service配置
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: nacos-server
    spec:
      ports:
      - port: 8848
        protocol: TCP
        targetPort: 8848
      selector:
        app: nacos-server
      type: ClusterIP
    • 部署A應用

      • 基準(base)版本的YAML如下。

        展開查看基準(base)版本的YAML檔案

        apiVersion: apps/v1
        kind: Deployment
        metadata:
          name: spring-cloud-a
        spec:
          replicas: 2
          selector:
            matchLabels:
              app: spring-cloud-a
          template:
            metadata:
              labels:
                app: spring-cloud-a
                msePilotAutoEnable: 'on'
                msePilotCreateAppName: spring-cloud-a
            spec:
              containers:
              - env:
                - name: JAVA_HOME
                  value: /usr/lib/jvm/java-1.8-openjdk/jre
                image: registry.cn-hangzhou.aliyuncs.com/mse-governance-demo/spring-cloud-a:3.0.1
                imagePullPolicy: Always
                name: spring-cloud-a
                ports:
                - containerPort: 20001
                livenessProbe:
                  tcpSocket:
                    port: 20001
                  initialDelaySeconds: 10
                  periodSeconds: 30
      • 灰階(gray)版本的YAML如下。

        展開查看灰階(gray)版本的YAML檔案

        apiVersion: apps/v1
        kind: Deployment
        metadata:
          name: spring-cloud-a-gray
        spec:
          replicas: 2
          selector:
            matchLabels:
              app: spring-cloud-a-gray
          strategy:
          template:
            metadata:
              labels:
                app: spring-cloud-a-gray
                msePilotAutoEnable: 'on'
                alicloud.service.tag: gray
                msePilotCreateAppName: spring-cloud-a
            spec:
              containers:
              - env:
                - name: JAVA_HOME
                  value: /usr/lib/jvm/java-1.8-openjdk/jre
                image: registry.cn-hangzhou.aliyuncs.com/mse-governance-demo/spring-cloud-a:3.0.1
                imagePullPolicy: Always
                name: spring-cloud-a-gray
                ports:
                - containerPort: 20001
                livenessProbe:
                  tcpSocket:
                    port: 20001
                  initialDelaySeconds: 10
                  periodSeconds: 30
    • 部署B應用

      • 基準(base)版本的YAML如下。

        展開查看基準(base)版本的YAML檔案

        apiVersion: apps/v1
        kind: Deployment
        metadata:
          name: spring-cloud-b
        spec:
          replicas: 2
          selector:
            matchLabels:
              app: spring-cloud-b
          strategy:
          template:
            metadata:
              labels:
                app: spring-cloud-b
                msePilotAutoEnable: 'on'
                msePilotCreateAppName: spring-cloud-b
            spec:
              containers:
              - env:
                - name: JAVA_HOME
                  value: /usr/lib/jvm/java-1.8-openjdk/jre
                image: registry.cn-hangzhou.aliyuncs.com/mse-governance-demo/spring-cloud-b:3.0.1
                imagePullPolicy: Always
                name: spring-cloud-b
                ports:
                - containerPort: 8080
                livenessProbe:
                  tcpSocket:
                    port: 20002
                  initialDelaySeconds: 10
                  periodSeconds: 30
    • 部署C應用

      • 基準(base)版本的YAML如下。

        展開查看基準(base)版本的YAML檔案

        apiVersion: apps/v1
        kind: Deployment
        metadata:
          name: spring-cloud-c
        spec:
          replicas: 2
          selector:
            matchLabels:
              app: spring-cloud-c
          template:
            metadata:
              labels:
                app: spring-cloud-c
                msePilotAutoEnable: 'on'
                msePilotCreateAppName: spring-cloud-c
            spec:
              containers:
              - env:
                - name: JAVA_HOME
                  value: /usr/lib/jvm/java-1.8-openjdk/jre
                image: registry.cn-hangzhou.aliyuncs.com/mse-governance-demo/spring-cloud-c:3.0.1
                imagePullPolicy: Always
                name: spring-cloud-c
                ports:
                - containerPort: 8080
                livenessProbe:
                  tcpSocket:
                    port: 20003
                  initialDelaySeconds: 10
                  periodSeconds: 30
      • 灰階(gray)版本的YAML如下。

        展開查看灰階(gray)版本的YAML檔案

        apiVersion: apps/v1
        kind: Deployment
        metadata:
          name: spring-cloud-c-gray
        spec:
          replicas: 2
          selector:
            matchLabels:
              app: spring-cloud-c-gray
          template:
            metadata:
              labels:
                app: spring-cloud-c-gray
                msePilotAutoEnable: 'on'
                alicloud.service.tag: gray
                msePilotCreateAppName: spring-cloud-c
            spec:
              containers:
              - env:
                - name: JAVA_HOME
                  value: /usr/lib/jvm/java-1.8-openjdk/jre
                image: registry.cn-hangzhou.aliyuncs.com/mse-governance-demo/spring-cloud-c:3.0.1
                imagePullPolicy: IfNotPresent
                name: spring-cloud-c-gray
                ports:
                - containerPort: 8080
                livenessProbe:
                  tcpSocket:
                    port: 20003
                  initialDelaySeconds: 10
                  periodSeconds: 30
  7. 針對入口應用A,配置兩個K8s Service。

    1. 登入Container Service控制台

    2. 在叢集管理頁左側導覽列,選擇網路 > 服務

    3. 服務頁面,選擇命名空間,然後單擊使用YAML建立資源,對模板進行相關配置,完成配置後單擊建立

      • spring-cloud-a-base對應A的base版本。

        展開查看YAML檔案

        apiVersion: v1
        kind: Service
        metadata:
          name: spring-cloud-a-base
        spec:
          ports:
            - name: http
              port: 20001
              protocol: TCP
              targetPort: 20001
          selector:
            app: spring-cloud-a
      • spring-cloud-a-gray對應A的gray版本。

        展開查看YAML檔案

        apiVersion: v1
        kind: Service
        metadata:
          name: spring-cloud-a-gray
        spec:
          ports:
            - name: http
              port: 20001
              protocol: TCP
              targetPort: 20001
          selector:
            app: spring-cloud-a-gray

步驟一:建立泳道組

  1. 登入MSE治理中心控制台,並在頂部功能表列選擇地區。

  2. 在左側導覽列,選擇治理中心 > 全链路灰度

  3. 全鏈路灰階頁面,單擊建立泳道組及泳道。如果您選擇的微服務空間內已經建立過泳道組,則單擊+建立泳道組

  4. 建立泳道組面板,設定泳道組相關參數,然後單擊確定

    配置項

    說明

    泳道組名稱

    自訂設定泳道組的名稱。

    入口類型

    選擇其他網關

    其他網關包含Nginx Ingress、APISIX、自建 Java 網關等,需要您自行在網關處實現灰階轉寄規則。

    泳道組涉及應用

    選擇您的入口應用或入口網關所涉及的所有相關服務。

    泳道組建立完成後,請檢查入口應用和所涉及的應用是否正確。您可以在全鏈路灰階頁面的泳道組及涉及的應用地區,查看您已建立的泳道組。如需變更泳道組資訊,請單擊右側的編輯表徵圖並修改相關資訊。

步驟二:建立泳道

  1. 全鏈路灰階頁面頂部,選擇和泳道組相同的地區,然後在頁面底部單擊點擊建立第一個分流泳道

    如果您選擇的微服務空間內已經建立過泳道,則單擊建立泳道

    重要

    加入全鏈路流量控制的應用,不推薦使用金絲雀發布和標籤路由功能。

  2. 建立泳道面板,設定流控泳道相關參數,然後單擊確定

    重要

    如果您的網關應用是Ingress網關,需要在Container Service管理主控台配置Ingress路由規則。

    配置項

    說明

    配置節點標籤

    • 配置方式:在容器ACK控制台中,在應用YAML的spec.template.metadata.labels下增加alicloud.service.tag: ${tag}

    • 設定標籤名:並為spec.template.metadata.labels增加如下兩個key-value索引值對。

      • msePilotCreateAppName:${AppName}

      • alicloud.service.tag:{tag}

    泳道名稱

    自訂設定流控泳道的名稱。

    泳道標籤

    完成配置節點標籤後,下拉框中會出現相應的標籤列表,選擇對應的標籤,則會自動添加相應的應用。

    完成泳道建立後,在全鏈路灰階流量分配地區,可以查看或配置泳道資訊。

    • 單擊表徵圖表徵圖,查看該泳道的流量比例。

    • 單擊應用狀態表徵圖表徵圖,可在泳道列表的操作列,設定該泳道應用的狀態。

      • 開啟泳道:單擊開啟,建立的泳道將會生效,即流量會按照泳道方式進行流轉,滿足規則的流量會優先流向標記有當前泳道對應標籤的應用版本,如果沒有對應標籤的應用版本則流向未打標的應用版本。

      • 關閉泳道:單擊關閉,關閉建立的泳道,即該應用往後的流量會流向未打標的應用版本。

      • 修改泳道:單擊編輯,修改當前泳道的配置資訊。

      • 刪除泳道:單擊刪除,刪除目標泳道。

步驟三:設定基準環境的Ingress規則

如果業務網域名稱為example.com,訪問example.com的請求流量只通過基準環境(線上環境),可以通過如下代碼設定基準環境的Ingress規則。

展開查看YAML檔案

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: spring-cloud-a
  namespace: default
spec:
  ingressClassName: mse
  rules:
    - host: example.com
      http:
        paths:
          - backend:
              service:
                name: spring-cloud-a-base
                port:
                  number: 20001
            path: /
            pathType: Prefix

使用curl命令訪問example.com路由到基準環境。

curl -H "host: example.com" http://47.98.xxx.xx/a

返回結果如下:

A[192.168.0.98][config=base] -> B[192.168.0.157] -> C[192.168.0.161]

步驟四:配置灰階環境的Ingress規則

如果基於Header策略來區分線上正式流量和灰階流量,希望帶有HTTP Header為x-user-id: 100的請求流量訪問example.com路由到灰階環境中,流量會優先訪問鏈路中各個應用對應的灰階版本,若無灰階版本,則會容災到基準版本。通過如下代碼配置灰階環境的Ingress規則。

展開查看YAML檔案

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    nginx.ingress.kubernetes.io/canary: 'true'
    nginx.ingress.kubernetes.io/canary-by-header: x-user-id
    nginx.ingress.kubernetes.io/canary-by-header-value: '100'
    mse.ingress.kubernetes.io/request-header-control-update: x-mse-tag gray
  name: spring-cloud-a-gray
  namespace: default
spec:
  ingressClassName: mse
  rules:
    - host: example.com
      http:
        paths:
          - backend:
              service:
                name: spring-cloud-a-gray
                port:
                  number: 20001
            path: /
            pathType: Prefix

上述代碼使用註解實現路由灰階發布、Header配置以及Header控制能力。關於註解的更多用法,請參見MSE Ingress進階用法

使用curl命令訪問example.com路由到灰階環境,其中帶有HTTP Header為x-user-id: 100的請求流量。

curl -H "host: example.com" -H "x-user-id: 100" http://47.98.xxx.xx/a

返回結果如下。灰階流量優先訪問了A和C的灰階版本,由於B沒有灰階版本,所以訪問了B的基準版本。

Agray[192.168.0.128][config=base] -> B[192.168.0.152] -> Cgray[192.168.0.151]

控制台查看應用的流量監控圖

  • 查看單個應用的監控圖

    1. 全鏈路灰階頁面,單擊目標泳道組頁簽。

    2. 泳道组及涉及的应用地區,單擊目標應用程式名稱,在右側會出現對應的QPS数据

  • 查看泳道組內所有應用的監控圖。

    1. 全鏈路灰階頁面,單擊目標泳道組頁簽。

    2. 應用 QPS 監控右側,單擊查看流量詳情,可以查看該泳道所有應用的流量監控圖。