全部產品
Search
文件中心

Microservices Engine:基於MSE實現微服務應用無損上下線

更新時間:Dec 27, 2024

為了避免在發布過程中造成流量損失,許多高並發請求量的應用系統通常選擇在流量較小時進行發布。雖然這種方法可以一定程度上解決問題,但不可控因素引起的營運成本也很高。MSE針對應用系統的上線與下線流程進行了深度最佳化。在應用下線階段,MSE引入了自適應等待和主動通知機制,確保所有待處理請求完成後再執行下線操作,從而避免突兀的服務中斷;在應用上線階段,通過就緒檢查,並將微服務的生命週期管理與發布的各個階段精準對齊,有效保證了新版本服務的穩定啟動。

前提條件

Demo架構說明

假設應用的架構由Zuul網關以及後端的微服務應用執行個體(Spring Cloud)構成,具體的後端調用鏈路有購物車應用A,交易中心應用B,庫存中心應用C,這些應用中的服務之間通過Nacos註冊中心實現服務註冊與發現。

在spring-cloud-zuul應用中,如下圖所示,其分別向spring-cloud-a的灰階版本和正常版本以QPS為100的速率同時進行服務調用。應用部署流量架構圖

部署應用並接入微服務治理

重要

由於Demo中有CronHPA任務,所以請先在叢集中安裝ack-kubernetes-cronhpa-controller組件。具體操作,請參見步驟一:安裝CronHPA組件

  1. 登入Container Service管理主控台,在左側導覽列選擇叢集

  2. 叢集列表頁面,單擊目的地組群名稱,然後在左側導覽列,選擇工作負載 > 無狀態

  3. 無狀態頁面,單擊使用YAML建立資源

  4. 樣本模板選擇自訂模板內容使用如下YAML,然後單擊建立

    本樣本Demo檔案取名為mse-demo.yaml。部署Zuul網關和A、B、C三個應用,其中A、B兩個應用分別部署一個基準版本和一個灰階版本,B應用的基準版本關閉了無損下線能力,灰階版本開啟了無損下線能力,C應用開啟了服務預熱能力,其中預熱時間長度為120秒。

    展開查看YAML檔案

    # 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
            msePilotCreateAppName: nacos-server
            msePilotAutoEnable: "on"
        spec:
          containers:
          - env:
            - name: MODE
              value: standalone
            image: registry.cn-shanghai.aliyuncs.com/yizhan/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
    
    #入口Zuul應用
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: spring-cloud-zuul
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: spring-cloud-zuul
      template:
        metadata:
          labels:
            app: spring-cloud-zuul
            msePilotCreateAppName: spring-cloud-zuul
            msePilotAutoEnable: "on"
        spec:
          containers:
            - env:
                - name: JAVA_HOME
                  value: /usr/lib/jvm/java-1.8-openjdk/jre
                - name: LANG
                  value: C.UTF-8
              image: registry.cn-shanghai.aliyuncs.com/yizhan/spring-cloud-zuul:1.0.1
              imagePullPolicy: Always
              name: spring-cloud-zuul
              ports:
                - containerPort: 20000
    
    # 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: 
          labels:
            app: spring-cloud-a
            msePilotCreateAppName: spring-cloud-a
            msePilotAutoEnable: "on"
        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
            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-gray
      name: spring-cloud-a-gray
    spec:
      replicas: 2
      selector:
        matchLabels:
          app: spring-cloud-a-gray
      strategy:
      template:
        metadata:
          labels:
            alicloud.service.tag: gray
            app: spring-cloud-a-gray
            msePilotCreateAppName: spring-cloud-a
            msePilotAutoEnable: "on"
        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-gray
            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:
          labels:
            app: spring-cloud-b
            msePilotCreateAppName: spring-cloud-b
            msePilotAutoEnable: "on"
        spec:
          containers:
          - env:
            - name: LANG
              value: C.UTF-8
            - name: JAVA_HOME
              value: /usr/lib/jvm/java-1.8-openjdk/jre
            - name: micro.service.shutdown.server.enable
              value: "false"
            - name: profiler.micro.service.http.server.enable
              value: "false"
            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-gray
      name: spring-cloud-b-gray
    spec:
      replicas: 2
      selector:
        matchLabels:
          app: spring-cloud-b-gray
      template:
        metadata:
          labels:
            alicloud.service.tag: gray
            app: spring-cloud-b-gray
            msePilotCreateAppName: spring-cloud-b
            msePilotAutoEnable: "on"
        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-gray
            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:
          labels:
            app: spring-cloud-c
            msePilotCreateAppName: spring-cloud-c
            msePilotAutoEnable: "on"
        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
    
    # HPA配置
    ---
    apiVersion: autoscaling.alibabacloud.com/v1beta1
    kind: CronHorizontalPodAutoscaler
    metadata:
      labels:
        controller-tools.k8s.io: "1.0"
      name: spring-cloud-b
    spec:
       scaleTargetRef:
          apiVersion: apps/v1beta2
          kind: Deployment
          name: spring-cloud-b
       jobs:
       - name: "scale-down"
         schedule: "0 0/5 * * * *"
         targetSize: 1
       - name: "scale-up"
         schedule: "10 0/5 * * * *"
         targetSize: 2
    ---
    apiVersion: autoscaling.alibabacloud.com/v1beta1
    kind: CronHorizontalPodAutoscaler
    metadata:
      labels:
        controller-tools.k8s.io: "1.0"
      name: spring-cloud-b-gray
    spec:
       scaleTargetRef:
          apiVersion: apps/v1beta2
          kind: Deployment
          name: spring-cloud-b-gray
       jobs:
       - name: "scale-down"
         schedule: "0 0/5 * * * *"
         targetSize: 1
       - name: "scale-up"
         schedule: "10 0/5 * * * *"
         targetSize: 2
    ---
    apiVersion: autoscaling.alibabacloud.com/v1beta1
    kind: CronHorizontalPodAutoscaler
    metadata:
      labels:
        controller-tools.k8s.io: "1.0"
      name: spring-cloud-c
    spec:
       scaleTargetRef:
          apiVersion: apps/v1beta2
          kind: Deployment
          name: spring-cloud-c
       jobs:
       - name: "scale-down"
         schedule: "0 2/5 * * * *"
         targetSize: 1
       - name: "scale-up"
         schedule: "10 2/5 * * * *"
         targetSize: 2
    
    
    # Zuul網關開啟SLB暴露展示頁面
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: zuul-slb
    spec:
      ports:
        - port: 80
          protocol: TCP
          targetPort: 20000
      selector:
        app: spring-cloud-zuul
      type: ClusterIP
    
    # A應用暴露K8s Service
    ---
    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-gray
    
    # Nacos Server SLB Service配置
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: nacos-slb
    spec:
      ports:
      - port: 8848
        protocol: TCP
        targetPort: 8848
      selector:
        app: nacos-server
      type: LoadBalancer
  5. 將部署應用接入微服務治理。具體操作,請參見ACK和ACS微服務應用接入MSE治理中心(Java版)

查看可觀測資料

由於spring-cloud-b應用和spring-cloud-b-gray應用均開啟了定時HPA,類比每5分鐘進行一次定時的擴縮容。您可以單擊應用程式名稱,然後單擊容器伸縮頁簽進行查看。

  • spring-cloud-b應用:

    image

  • spring-cloud-b-gray應用:

    image

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

  2. 在左側導覽列,選擇治理中心 > 应用治理,單擊spring-cloud-a應用資源卡片。

  3. 应用概览頁面顯示該應用相關的可觀測資料。

    從資料中可以看出:

    • spring-cloud-a-gray版本的流量在Pod擴縮容的過程中請求錯誤數為0,無流量損失。

    • spring-cloud-a版本由於關閉了無損下線功能,在Pod擴縮容的過程中有20個從spring-cloud-a發到spring-cloud-b的請求出現報錯,發生了請求流量損耗。

開啟無損上線

在spring-cloud-c應用開啟了定時HPA類比應用啟動的過程,每隔5分鐘做一次伸縮,在第2分鐘第0秒縮容到1個節點,在第2分鐘第10秒擴容到2個節點。image

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

  2. 在左側導覽列,選擇治理中心 > 应用治理,單擊spring-cloud-c應用資源卡片。

  3. 在左側導覽列,選擇流量治理,然後選擇无损上下线頁簽,開啟无损上线開關,在提示信息對話方塊,單擊確定。預熱時間長度預設設定為120秒。

    開啟預熱功能的應用重啟後的流量會隨時間緩慢增加,在一些應用啟動過程中需要預建串連池和緩衝等資源的慢啟動情境,開啟服務預熱能有效保護應用啟動過程中緩衝資源有序建立保障應用安全啟動並做到流量無損。