天天看點

如何用20分鐘就能獲得同款企業級全鍊路灰階能力?背景MSE 微服務治理全鍊路灰階特點大規模生産實踐的場景全鍊路灰階的實踐總結規範釋出流程尾

作者:十眠

稽核&校對:望陶、亦盞

編輯&排版:雯燕

今年雙 11,雲原生中間件完成了開源、自研、商業化三位一體,全面更新到中間件雲産品。MSE 微服務治理通過 Dubbo3.0 支撐了阿裡集團核心業務雙 11 的流量洪峰,截止目前集團内 50% 的使用者已經習慣使用 MSE 微服務治理 HSF 和 Dubbo3.0 應用,今天我們來細聊一下 MSE 服務治理專業版中的全鍊路灰階能力,以及它在生産大規模實踐的一些場景。

背景

微服務架構下,有一些需求開發,涉及到微服務調用鍊路上的多個微服務同時發生了改動,需要通過灰階釋出方式來更好地控制新版本服務上線的風險和爆炸半徑。通常每個微服務都會有灰階環境或分組來接受灰階流量,我們希望通過進入上遊灰階環境的流量,也能進入下遊灰階的環境中,確定 1 個請求始終在灰階環境中傳遞,即使這個調用鍊路上有一些微服務沒有灰階環境,這些應用請求下遊的時候依然能夠回到灰階環境中。通過 MSE 提供的全鍊路灰階能力,可以在不需要修改任何您的業務代碼的情況下,能夠輕松實作上述能力。

MSE 微服務治理全鍊路灰階特點

全鍊路灰階作為 MSE 服務治理專業版中的拳頭功能,具備以下六大特點

  • 可通過定制規則引入精細化流量

除了簡單地按照比例進行流量引入外,我們還支援 Spring Cloud 與 Dubbo 流量按規則引入,Spring Cloud 流量可根據請求的 cookie、header、param 參數或随機百分比引入流量,Dubbo 流量可按照服務、方法、參數來引入。

如何用20分鐘就能獲得同款企業級全鍊路灰階能力?背景MSE 微服務治理全鍊路灰階特點大規模生産實踐的場景全鍊路灰階的實踐總結規範釋出流程尾
如何用20分鐘就能獲得同款企業級全鍊路灰階能力?背景MSE 微服務治理全鍊路灰階特點大規模生産實踐的場景全鍊路灰階的實踐總結規範釋出流程尾
如何用20分鐘就能獲得同款企業級全鍊路灰階能力?背景MSE 微服務治理全鍊路灰階特點大規模生産實踐的場景全鍊路灰階的實踐總結規範釋出流程尾
如何用20分鐘就能獲得同款企業級全鍊路灰階能力?背景MSE 微服務治理全鍊路灰階特點大規模生産實踐的場景全鍊路灰階的實踐總結規範釋出流程尾
  • 全鍊路隔離流量泳道

1) 通過設定流量規則對所需流量進行“染色”,“染色”流量會路由到灰階機器。

2) 灰階流量攜帶灰階标往下遊傳遞,形成灰階專屬環境流量泳道,無灰階環境應用會預設選擇未打标的基線環境。

  • 端到端的穩定基線環境

未打标的應用屬于基線穩定版本的應用,即穩定的線上環境。當我們将釋出對應的灰階版本代碼,然後可以配置規則定向引入特定的線上流量,控制灰階代碼的風險。

  • 流量一鍵動态切流

流量規則定制後,可根據需求進行一鍵停啟,增删改查,實時生效。灰階引流更便捷。

  • 低成本接入,基于 Java Agent 技術實作無需修改一行業務代碼

MSE 微服務治理能力基于 Java Agent 位元組碼增強的技術實作,無縫支援市面上近 5 年的所有 Spring Cloud 和 Dubbo 的版本,使用者不用改一行代碼就可以使用,不需要改變業務的現有架構,随時可上可下,沒有綁定。隻需開啟 MSE 微服務治理專業版,線上配置,實時生效。

  • 具備無損上下線能力,使得釋出更加絲滑

應用開啟 MSE 微服務治理後就具備無損上下線能力,大流量下的釋出、復原、擴容、縮容等場景,均能保證流量無損。

大規模生産實踐的場景

本文主要介紹 MSE 微服務治理在支援大客戶過程中總結抽象出來的常用的幾個全鍊路灰階方案生産落地實踐的場景。

場景一:對經過機器的流量進行自動染色,實作全鍊路灰階

如何用20分鐘就能獲得同款企業級全鍊路灰階能力?背景MSE 微服務治理全鍊路灰階特點大規模生産實踐的場景全鍊路灰階的實踐總結規範釋出流程尾
  • 進入帶 tag 的節點後續調用優先選擇帶有相同 tag 的節點,即對經過 tag 節點的流量進行“染色”。
  • 有 tag 的調用鍊路上找不到相同 tag 的節點,則 fallback 到無 tag 的節點。
  • 有 tag 的調用鍊路經過無 tag 的節點,如果鍊路後續調用有 tag 的節點,則恢複 tag 調用的模式。

場景二:通過給流量帶上特定的 header 實作全鍊路灰階

如何用20分鐘就能獲得同款企業級全鍊路灰階能力?背景MSE 微服務治理全鍊路灰階特點大規模生産實踐的場景全鍊路灰階的實踐總結規範釋出流程尾
如何用20分鐘就能獲得同款企業級全鍊路灰階能力?背景MSE 微服務治理全鍊路灰階特點大規模生産實踐的場景全鍊路灰階的實踐總結規範釋出流程尾

用戶端通過在請求中增加制定環境的辨別,接入層根據表示進行轉發至表示對應環境的網關,對應環境的網關通過隔離插件調用辨別對應的項目隔離環境,請求在業務項目隔離環境中閉環。

場景三:通過自定義路由規則來進行全鍊路灰階

如何用20分鐘就能獲得同款企業級全鍊路灰階能力?背景MSE 微服務治理全鍊路灰階特點大規模生産實踐的場景全鍊路灰階的實踐總結規範釋出流程尾
如何用20分鐘就能獲得同款企業級全鍊路灰階能力?背景MSE 微服務治理全鍊路灰階特點大規模生産實踐的場景全鍊路灰階的實踐總結規範釋出流程尾

通過在灰階請求中增加指定的 header,且整條調用鍊路會将該 header 透傳下去,隻需在對應的應用配置該 header 相關的路由規則,帶指定 header 的灰階請求進入灰階機器,即可按需實作全鍊路流量灰階。

如何用20分鐘就能獲得同款企業級全鍊路灰階能力?背景MSE 微服務治理全鍊路灰階特點大規模生産實踐的場景全鍊路灰階的實踐總結規範釋出流程尾

全鍊路灰階的實踐

我們如何快速獲得上述同款全鍊路灰階的能力呢?下面我會帶大家從 0 到 1 快速搭建我們的全鍊路灰階能力。

我們假設應用的架構由 Ingress-nginx 以及後端的微服務架構(Spring Cloud)來組成,後端調用鍊路有 3 跳,購物車(a),交易中心(b),庫存中心(c),他們通過 Nacos 注冊中心做服務發現,用戶端通過用戶端或者是 H5 頁面來通路後端服務。

前提條件

安裝 Ingress-nginx 元件

通路容器服務控制台,打開應用目錄,搜尋 ​

ack-ingress-nginx

​ ,選擇命名空間 ​

kube-system

​,點選建立,安裝完成後,在 ​

kube-system

​ 命名空間中會看到一個 deployment ​

ack-ingress-nginx-default-controller

​ ,表明安裝成功。

$ kubectl get deployment -n kube-system
NAME                                      READY   UP-TO-DATE   AVAILABLE   AGE
ack-ingress-nginx-default-controller      2/2     2            2           18h      

開啟 MSE 微服務治理專業版

  • 點選開通 MSE 微服務治理專業版 以使用全鍊路灰階能力。
  • 通路容器服務控制台,打開應用目錄,搜尋 ack-mse-pilot ,點選建立。
  • 在 MSE 服務治理控制台,打開 K8s 叢集清單,選擇對應叢集,對應命名空間,并打開微服務治理。

部署 Demo 應用程式

将下面的檔案儲存到 ingress-gray.yaml 中,并執行 ​

kubectl apply -f ingress-gray.yaml

​ 以部署應用,這裡我們将要部署 A, B, C 三個應用,每個應用分别部署一個基線版本和一個灰階版本。

# A 應用 base 版本
---
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: spring-cloud-a
  name: spring-cloud-a
spec:
  replicas: 2
  selector:
    matchLabels:
      app: spring-cloud-a
  template:
    metadata:
      annotations:
        msePilotCreateAppName: spring-cloud-a
      labels:
        app: spring-cloud-a
    spec:
      containers:
      - env:
        - name: LANG
          value: C.UTF-8
        - name: JAVA_HOME
          value: /usr/lib/jvm/java-1.8-openjdk/jre
        image: registry.cn-shanghai.aliyuncs.com/yizhan/spring-cloud-a:0.1-SNAPSHOT
        imagePullPolicy: Always
        name: spring-cloud-a
        ports:
        - containerPort: 20001
          protocol: TCP
        resources:
          requests:
            cpu: 250m
            memory: 512Mi
        livenessProbe:
          tcpSocket:
            port: 20001
          initialDelaySeconds: 10
          periodSeconds: 30
      
# A 應用 gray 版本
---            
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: spring-cloud-a-new
  name: spring-cloud-a-new
spec:
  replicas: 2
  selector:
    matchLabels:
      app: spring-cloud-a-new
  strategy:
  template:
    metadata:
      annotations:
        alicloud.service.tag: gray
        msePilotCreateAppName: spring-cloud-a
      labels:
        app: spring-cloud-a-new
    spec:
      containers:
      - env:
        - name: LANG
          value: C.UTF-8
        - name: JAVA_HOME
          value: /usr/lib/jvm/java-1.8-openjdk/jre
        - name: profiler.micro.service.tag.trace.enable
          value: "true"
        image: registry.cn-shanghai.aliyuncs.com/yizhan/spring-cloud-a:0.1-SNAPSHOT
        imagePullPolicy: Always
        name: spring-cloud-a-new
        ports:
        - containerPort: 20001
          protocol: TCP
        resources:
          requests:
            cpu: 250m
            memory: 512Mi
        livenessProbe:
          tcpSocket:
            port: 20001
          initialDelaySeconds: 10
          periodSeconds: 30
            
# B 應用 base 版本
---
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: spring-cloud-b
  name: spring-cloud-b
spec:
  replicas: 2
  selector:
    matchLabels:
      app: spring-cloud-b
  strategy:
  template:
    metadata:
      annotations:
        msePilotCreateAppName: spring-cloud-b
      labels:
        app: spring-cloud-b
    spec:
      containers:
      - env:
        - name: LANG
          value: C.UTF-8
        - name: JAVA_HOME
          value: /usr/lib/jvm/java-1.8-openjdk/jre
        image: registry.cn-shanghai.aliyuncs.com/yizhan/spring-cloud-b:0.1-SNAPSHOT
        imagePullPolicy: Always
        name: spring-cloud-b
        ports:
        - containerPort: 8080
          protocol: TCP
        resources:
          requests:
            cpu: 250m
            memory: 512Mi
        livenessProbe:
          tcpSocket:
            port: 20002
          initialDelaySeconds: 10
          periodSeconds: 30
            
# B 應用 gray 版本  
---
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: spring-cloud-b-new
  name: spring-cloud-b-new
spec:
  replicas: 2
  selector:
    matchLabels:
      app: spring-cloud-b-new
  template:
    metadata:
      annotations:
        alicloud.service.tag: gray
        msePilotCreateAppName: spring-cloud-b
      labels:
        app: spring-cloud-b-new
    spec:
      containers:
      - env:
        - name: LANG
          value: C.UTF-8
        - name: JAVA_HOME
          value: /usr/lib/jvm/java-1.8-openjdk/jre
        image: registry.cn-shanghai.aliyuncs.com/yizhan/spring-cloud-b:0.1-SNAPSHOT
        imagePullPolicy: Always
        name: spring-cloud-b-new
        ports:
        - containerPort: 8080
          protocol: TCP
        resources:
          requests:
            cpu: 250m
            memory: 512Mi
        livenessProbe:
          tcpSocket:
            port: 20002
          initialDelaySeconds: 10
          periodSeconds: 30
            
# C 應用 base 版本
---
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: spring-cloud-c
  name: spring-cloud-c
spec:
  replicas: 2
  selector:
    matchLabels:
      app: spring-cloud-c
  template:
    metadata:
      annotations:
        msePilotCreateAppName: spring-cloud-c
      labels:
        app: spring-cloud-c
    spec:
      containers:
      - env:
        - name: LANG
          value: C.UTF-8
        - name: JAVA_HOME
          value: /usr/lib/jvm/java-1.8-openjdk/jre
        image: registry.cn-shanghai.aliyuncs.com/yizhan/spring-cloud-c:0.1-SNAPSHOT
        imagePullPolicy: Always
        name: spring-cloud-c
        ports:
        - containerPort: 8080
          protocol: TCP
        resources:
          requests:
            cpu: 250m
            memory: 512Mi
        livenessProbe:
          tcpSocket:
            port: 20003
          initialDelaySeconds: 10
          periodSeconds: 30
            
# C 應用 gray 版本
---
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: spring-cloud-c-new
  name: spring-cloud-c-new
spec:
  replicas: 2
  selector:
    matchLabels:
      app: spring-cloud-c-new
  template:
    metadata:
      annotations:
        alicloud.service.tag: gray
        msePilotCreateAppName: spring-cloud-c
      labels:
        app: spring-cloud-c-new
    spec:
      containers:
      - env:
        - name: LANG
          value: C.UTF-8
        - name: JAVA_HOME
          value: /usr/lib/jvm/java-1.8-openjdk/jre
        image: registry.cn-shanghai.aliyuncs.com/yizhan/spring-cloud-c:0.1-SNAPSHOT
        imagePullPolicy: IfNotPresent
        name: spring-cloud-c-new
        ports:
        - containerPort: 8080
          protocol: TCP
        resources:
          requests:
            cpu: 250m
            memory: 512Mi
        livenessProbe:
          tcpSocket:
            port: 20003
          initialDelaySeconds: 10
          periodSeconds: 30

# Nacos Server
---
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: nacos-server
  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: nacos/nacos-server:latest
        imagePullPolicy: Always
        name: nacos-server
        resources:
          requests:
            cpu: 250m
            memory: 512Mi
      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      

動手實踐

有時候,我們可以通過不同的域名來區分線上基線環境和灰階環境,灰階環境有單獨的域名可以配置,假設我們通過通路 www.gray.com 來請求灰階環境,通路 www.base.com 走基線環境。

如何用20分鐘就能獲得同款企業級全鍊路灰階能力?背景MSE 微服務治理全鍊路灰階特點大規模生産實踐的場景全鍊路灰階的實踐總結規範釋出流程尾

調用鍊路 Ingress-nginx -> A -> B -> C ,其中 A 可以是一個 spring-boot 的應用。

注意:入口應用 A 的 gray 和 A 的 base 環境,需要在 MSE 服務治理控制台打開 A 應用的按照流量比例透傳開關,表示開啟向後透傳目前環境的标簽的功能。這樣, 當 Ingress-nginx 路由 A 的 gray 之後,即使請求中沒有攜帶任何 header,因為開啟了此開關,是以往後調用的時候會自動添加 x-mse-tag:gray 這個 header,其中的 header的值 gray 來自于 A 應用配置的标簽資訊。如果原來的請求中帶有 x-mse-tag:gray則會以原來請求中的标簽優先。

針對入口應用 A ,配置兩個 k8s service, spring-cloud-a-base 對應 A 的 base 版本,spring-cloud-a-gray 對應 A 的 gray 版本。

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

---
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-new      

配置入口的 Ingress 規則,通路 www.base.com 路由到 A 應用的 base 版本,通路 www.gray.com 路由到 A 應用的 gray 版本。

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: spring-cloud-a-base
spec:
  rules:
  - host: www.base.com
    http:
      paths:
      - backend:
          serviceName: spring-cloud-a-base
          servicePort: 20001
        path: /

---
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: spring-cloud-a-gray
spec:
  rules:
  - host: www.gray.com
    http:
      paths:
      - backend:
          serviceName: spring-cloud-a-gray
          servicePort: 20001
        path: /      
結果驗證

此時,通路 www.base.com 路由到 基線環境

curl -H"Host:www.base.com" http://106.14.155.223/a
A[172.18.144.155] -> B[172.18.144.120] -> C[172.18.144.79]      

此時,通路 www.gray.com 路由到灰階環境

curl -H"Host:www.gray.com" http://106.14.155.223/a
Agray[172.18.144.160] -> Bgray[172.18.144.57] -> Cgray[172.18.144.157]      

進一步的,如果入口應用 A 沒有灰階環境,通路到 A 的 base 環境,又需要在 A -> B 的時候進入灰階環境,則可以通過增加一個特殊的 header ​

x-mse-tag

​ 來實作,header 的值是想要去的環境的标簽,例如 ​

gray

​。

curl -H"Host:www.base.com"  -H"x-mse-tag:gray" http://106.14.155.223/a
A[172.18.144.155] -> Bgray[172.18.144.139] -> Cgray[172.18.144.8]      

可以看到第一跳,進入了 A 的 base 環境,但是 A->B 的時候又重新回到了灰階環境。

這種使用方式的好處是,配置簡單,隻需要在 Ingress 處配置好規則,某個應用需要灰階釋出的時候,隻需要在灰階環境中部署好應用,灰階流量自然會進入到灰階機器中,如果驗證沒問題,則将灰階的鏡像釋出到基線環境中;如果一次變更有多個應用需要灰階釋出,則把他們都加入到灰階環境中即可。

最佳實踐
  1. 給所有灰階環境的應用打上 gray 标,基線環境的應用預設不打标。
  1. 線上常态化引流 2% 的流量進去灰階環境中

有些用戶端沒法改寫域名,希望能通路 www.demo.com 通過傳入不同的 header 來路由到灰階環境。例如下圖中,通過添加 x-mse-tag:gray 這個 header,來通路灰階環境。

如何用20分鐘就能獲得同款企業級全鍊路灰階能力?背景MSE 微服務治理全鍊路灰階特點大規模生産實踐的場景全鍊路灰階的實踐總結規範釋出流程尾
如何用20分鐘就能獲得同款企業級全鍊路灰階能力?背景MSE 微服務治理全鍊路灰階特點大規模生産實踐的場景全鍊路灰階的實踐總結規範釋出流程尾

這個時候 demo 的Ingress 規則如下,注意這裡增加了 ​

nginx.ingress.kubernetes.io/canary

​ 相關的多條規則

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: spring-cloud-a-base
spec:
  rules:
  - host: www.demo.com
    http:
      paths:
      - backend:
          serviceName: spring-cloud-a-base
          servicePort: 20001
        path: /
---
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: spring-cloud-a-gray
  annotations:
    nginx.ingress.kubernetes.io/canary: "true"
    nginx.ingress.kubernetes.io/canary-by-header: "x-mse-tag"
    nginx.ingress.kubernetes.io/canary-by-header-value: "gray"
    nginx.ingress.kubernetes.io/canary-weight: "0"
spec:
  rules:
  - host: www.base.com
    http:
      paths:
      - backend:
          serviceName: spring-cloud-a-gray
          servicePort: 20001
        path: /      

此時,通路 www.demo.com 路由到基線環境

curl -H"Host:www.demo.com" http://106.14.155.223/a
A[172.18.144.155] -> B[172.18.144.56] -> C[172.18.144.156]      

如何通路灰階環境呢?隻需要在請求中增加一個header ​

x-mse-tag:gray

​ 即可。

curl -H"Host:www.demo.com"  -H"x-mse-tag:gray" http://106.14.155.223/a
Agray[172.18.144.82] -> Bgray[172.18.144.57] -> Cgray[172.18.144.8]      

可以看到 Ingress 根據這個header直接路由到了 A 的 gray 環境中。

更進一步

還可以借助 Ingress 實作更複雜的路由,比如用戶端已經帶上了某個header,想要利用現成的 header來實作路由,而不用新增一個 header,例如下圖所示,假設我們想要 ​

x-user-id

​ 為 100 的請求進入灰階環境。

如何用20分鐘就能獲得同款企業級全鍊路灰階能力?背景MSE 微服務治理全鍊路灰階特點大規模生産實踐的場景全鍊路灰階的實踐總結規範釋出流程尾
如何用20分鐘就能獲得同款企業級全鍊路灰階能力?背景MSE 微服務治理全鍊路灰階特點大規模生産實踐的場景全鍊路灰階的實踐總結規範釋出流程尾

隻需要增加下面這 4 條規則:

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: spring-cloud-a-base
spec:
  rules:
  - host: www.demo.com
    http:
      paths:
      - backend:
          serviceName: spring-cloud-a-base
          servicePort: 20001
        path: /
---
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: spring-cloud-a-base-gray
  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"
    nginx.ingress.kubernetes.io/canary-weight: "0"
spec:
  rules:
  - host: www.demo.com
    http:
      paths:
      - backend:
          serviceName: spring-cloud-a-gray
          servicePort: 20001
        path: /      

通路的時候帶上特殊的 header ,滿足條件進入灰階環境

curl -H"Host:www.demo.com"  -H"x-user-id:100" http://106.14.155.223/a
Agray[172.18.144.93] -> Bgray[172.18.144.24] -> Cgray[172.18.144.25]      

不滿足條件的請求,進入基線環境:

curl -H"Host:www.demo.com"  -H"x-user-id:101" http://106.14.155.223/a
A[172.18.144.91] -> B[172.18.144.22] -> C[172.18.144.95]      

相比場景一這樣的好處是,用戶端的域名不變,隻需要通過請求來區分。

有時候我們不想要自動透傳且自動路由,而是希望微服務調用鍊上下遊上的每個應用能自定義灰階規則,例如 B 應用希望控制隻有滿足自定義規則的請求才會路由到 B 應用這裡,而 C 應用有可能希望定義和 B 不同的灰階規則,這時應該如何配置呢,場景參見如下圖:

如何用20分鐘就能獲得同款企業級全鍊路灰階能力?背景MSE 微服務治理全鍊路灰階特點大規模生産實踐的場景全鍊路灰階的實踐總結規範釋出流程尾
如何用20分鐘就能獲得同款企業級全鍊路灰階能力?背景MSE 微服務治理全鍊路灰階特點大規模生産實踐的場景全鍊路灰階的實踐總結規範釋出流程尾
注意,最好把場景一和二中配置的參數清除掉。

第一步,需要在入口應用 A 處(最好是所有的入口應用都增加該環境變量,包括 gray 和 base) 增加一個環境變量:​

alicloud.service.header=x-user-id

​,​

x-user-id

​ 是需要透傳的 header,它的作用是識别該 header 并做自動透傳。

注意這裡不要使用 x-mse-tag, 它是系統預設的一個 header,有特殊的邏輯。

第二步,在中間的 B 應用處,在 MSE 控制台配置标簽路由規則

如何用20分鐘就能獲得同款企業級全鍊路灰階能力?背景MSE 微服務治理全鍊路灰階特點大規模生産實踐的場景全鍊路灰階的實踐總結規範釋出流程尾
如何用20分鐘就能獲得同款企業級全鍊路灰階能力?背景MSE 微服務治理全鍊路灰階特點大規模生産實踐的場景全鍊路灰階的實踐總結規範釋出流程尾

第三步,在 Ingress 處配置路由規則,這一步參考場景二,并采用如下配置:

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: spring-cloud-a-base
spec:
  rules:
  - host: www.base.com
    http:
      paths:
      - backend:
          serviceName: spring-cloud-a-base
          servicePort: 20001
        path: /
---
apiVersion: networking.k8s.io/v1beta1
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'
    nginx.ingress.kubernetes.io/canary-weight: '0'
  name: spring-cloud-a-gray
spec:
  rules:
    - host: www.base.com
      http:
        paths:
          - backend:
              serviceName: spring-cloud-a-gray
              servicePort: 20001
            path: /      

測試驗證,通路灰階環境,帶上滿足條件的 header,路由到 B 的灰階環境中。

curl 120.77.215.62/a -H "Host: www.base.com" -H "x-user-id: 100" 
Agray[192.168.86.42] -> Bgray[192.168.74.4] -> C[192.168.86.33]      

通路灰階環境,帶上不滿足條件的 header,路由到 B 的base環境中。

curl 120.77.215.62/a -H "Host: www.base.com" -H "x-user-id: 101" 
A[192.168.86.35] -> B[192.168.73.249] -> C[192.168.86.33]      

去掉 Ingress Canary 配置,通路 base A 服務(基線環境入口應用需要加上 alicloud.service.header 環境變量),帶上滿足條件的 header,路由到 B 的灰階環境中。

curl 120.77.215.62/a -H "Host: www.base.com" -H "x-user-id: 100" 
A[192.168.86.35] -> Bgray[192.168.74.4] -> C[192.168.86.33]      

通路 base 環境,帶上不滿足條件的 header,路由到 B 的 base 環境中。

curl 120.77.215.62/a -H "Host: www.base.com" -H "x-user-id: 101" 
A[192.168.86.35] -> B[192.168.73.249] -> C[192.168.86.33]      

總結

20 分鐘快速實踐完具有很大技術難度的全鍊路灰階能力,全鍊路灰階其實并不是那麼難!

基于 MSE 服務治理的全鍊路灰階能力,我們可以快速落地企業級的全鍊路灰階能力,以上三種場景是我們在生産實踐中大規模落地的标準場景,當然我們可以基于 MSE 服務治理的能力根據自己的業務個性化定制與适配;即使在多種流量來源的背景下,也能做到按照業務定制精準引流。

同時 MSE 服務治理專業版的可觀測性能力使得灰階有效性得到可衡量,灰沒灰到,灰得咋樣,做到“心裡有數”。

  • 灰階流量秒級監控
如何用20分鐘就能獲得同款企業級全鍊路灰階能力?背景MSE 微服務治理全鍊路灰階特點大規模生産實踐的場景全鍊路灰階的實踐總結規範釋出流程尾

規範釋出流程

日常釋出中,我們常常會有如下一些錯誤的想法:

  • 這次改動的内容比較小,而且上線要求比較急,就不需要測試直接釋出上線好了。
  • 釋出不需要走灰階流程,快速釋出上線即可。
  • 灰階釋出沒有什麼用,就是一個流程而已,釋出完就直接釋出線上,不用等待觀察。
  • 雖然灰階釋出很重要,但是灰階環境很難搭建,耗時耗力優先級并不高。

這些想法都可能讓我們進行一次錯誤的釋出,不少故障是因為釋出直接或間接引起。是以提升釋出的品質,減少錯誤的發生,是有效減少線上故障的一個關鍵環節。做到安全的釋出,我們需要規範釋出的流程。

如何用20分鐘就能獲得同款企業級全鍊路灰階能力?背景MSE 微服務治理全鍊路灰階特點大規模生産實踐的場景全鍊路灰階的實踐總結規範釋出流程尾

随着微服務的流行,越來越多公司使用了微服務架構,微服務以其高内聚、低耦合等特性,提供了更好的容錯性,也更适應業務的快速疊代,為開發人員帶來了很多的便利性。但是随着業務的發展,微服務拆分越來越複雜,微服務的治理也成了一個比較令人頭疼的問題。

單單拿全鍊路灰階來看,為了保證應用新版本上線前的功能正确性的驗證同時需要兼顧應用釋出的效率,如果我們應用的規模很小,我們可以直接通過維護多套環境來保證釋出的正确性。但是當我們的業務發展到龐大且複雜程度時,假設我們的系統由 100 個微服務構成,即使測試/灰階環境每個服務占用 1 到 2 個 pod,那麼多套環境下來我們需要面臨巨大的成本與運維環境帶來的效率的挑戰。

有沒有更加簡單且高效的方法來解決微服務治理的難題?

MSE 微服務引擎将推出服務治理專業版,提供開箱即用且完整專業的微服務治了解決方案,幫助企業更好地實作微服務治理能力。如果您的系統也可以像本文描述的那樣,快速具備完整的全鍊路灰階能力,并基于該能力進行進一步的微服務治理實踐,不僅可以節省客觀的人力與成本,還可以讓您的企業在微服務領域的探索更加有底氣。

了解更多相關資訊,請掃描下方二維碼或搜尋微信号(AlibabaCloud888)添加雲原生小助手!擷取更多相關資訊!

如何用20分鐘就能獲得同款企業級全鍊路灰階能力?背景MSE 微服務治理全鍊路灰階特點大規模生産實踐的場景全鍊路灰階的實踐總結規範釋出流程尾