全部產品
Search
文件中心

Alibaba Cloud Service Mesh:使用ASM回退機制

更新時間:Jun 30, 2024

當服務調用執行未成功時,回退機制提供替代的另外執行路徑。當某個微服務發生故障或無法使用時,回退機制會調用一個備用的服務來處理請求,以確保整個系統的穩定性和可用性。例如,當一個服務端點不可用時,可以使用回退機制將請求轉寄到一個備用的服務版本,確保用戶端請求能夠繼續正常運行,而不會出現錯誤或中斷。ASM支援在VirtualService中定義fallback參數以支援要求服務失敗時的回退機制。本文介紹如何使用ASM回退機制。

前提條件

配置說明

本文以Bookinfo樣本中的reviews服務為例。當productpage服務訪問reivews服務的三個版本v1、v2、v3時,如果v3版本不可用,將執行回退機制降級訪問v2版本,並且不返回503失敗資訊。

您可以單擊設定檔,直接下載本文使用的相關YAML檔案。

步驟一:訪問Bookinfo樣本

  1. 使用以下內容,建立reviews.yaml檔案,聲明reviews服務的v1、v2、v3三個版本。

    apiVersion: networking.istio.io/v1alpha3
    kind: DestinationRule
    metadata:
      name: reviews
    spec:
      host: reviews
      subsets:
      - name: v1
        labels:
          version: v1
      - name: v2
        labels:
          version: v2
      - name: v3
        labels:
          version: v3
  2. 在ASM執行個體對應的KubeConfig環境下,執行以下命令,部署DestinationRule。

    kubectl apply -f reviews.yaml
  3. 任選以下方式,擷取網關的IP。

    • 方式一:通過以下命令擷取。

    kubectl get svc -n istio-system  istio-ingressgateway -o jsonpath='{.status.loadBalancer.ingress[0].ip}'
    • 方式二:通過ASM控制台的入口網關頁面擷取網關IP。具體操作,請參見擷取ASM網關地址

  4. 在瀏覽器中訪問http://${YourGatewayIp}/productpage

    ${YourGatewayIp}為上一步擷取的網關IP。您可以通過Reviews served by的值或星星來判斷版本。v1版本沒有星星,v2版本為黑色星星,v3版本為紅色星星。

    例如,下圖reviews-v2表示v2版本,星星為黑色。v2版本樣本..png

    不斷重新整理頁面,您可以看到請求reviews時,負載平衡到reviews的v1、v2、v3三個版本。

步驟二:定義訪問reviews的路由和回退規則

  1. 使用以下內容,建立reviews-route-fallback-sample1.yaml檔案。

    apiVersion: networking.istio.io/v1beta1
    kind: VirtualService
    metadata:
      name: reviews-route
      namespace: default
    spec:
      hosts:
        - reviews
      http:
        - route:
            - destination:
                host: reviews
                subset: v3
              fallback:
                target:
                  host: reviews
                  subset: v2
    
  2. 在ASM執行個體對應的KubeConfig環境下,執行以下命令,部署訪問reviews的路由和回退規則。

    kubectl apply -f reviews-route-fallback-sample1.yaml
  3. 在瀏覽器中訪問http://${YourGatewayIp}/productpage,並不斷重新整理頁面。

    可以看到請求一直在reviews的v3版本上。v3版本..png

  4. 執行以下命令,人為類比reviews-v3版本故障,將reviews-v3的副本執行個體數修改為0。

    kubectl scale deployment reviews-v3 --replicas=0
  5. 在瀏覽器中訪問http://${YourGatewayIp}/productpage,並不斷重新整理頁面。

    可以看到請求正確回退到reviews的v2的版本上。您可以通過在自訂訪問日誌格式中添加Fallback相關欄位,然後查看日誌,判斷是否進行了回退。

    展開查看是否進行了回退

    1. 在自訂訪問日誌格式中添加如下欄位。具體操作,請參見自訂資料面訪問日誌內容

      欄位

      取值

      說明

      fallback_path

      %DYNAMIC_METADATA(com.aliyun.fallback:fallback-path)%

      回退的具體路徑。例如A:B表示A回退到B;A:B:C表示A回退到B,因為B也不健康,所以回退到C。

      fallback_final_cluster_name

      %DYNAMIC_METADATA(com.aliyun.fallback:final-cluster)%

      若回退,則回退到對應的目的地組群。例如當service1|v1不存在時,回退到service|base。

      fallback_result

      %DYNAMIC_METADATA(com.aliyun.fallback:fallback-result)%

      回退的結果,若失敗則發送給原路由的叢集。

      自訂日誌格式..png

    2. 查看produpage-v1的istio-proxy的日誌。

      當reviews-v3回退到reviews-v2時,日誌樣本如下:

      {
          "authority":"reviews:9080",
          "authority_for":"reviews:9080",
          "bytes_received":"0",
          "bytes_sent":"442",
          "downstream_local_address":"192.168.255.46:9080",
          "downstream_remote_address":"172.16.0.252:57238",
          "duration":"10",
          "fallback_path":"outbound|9080|v3|reviews.default.svc.cluster.local:outbound|9080|v2|reviews.default.svc.cluster.local",
          "fallback_final_cluster_name":"outbound|9080|v2|reviews.default.svc.cluster.local",
          "fallback_result":"fallback successful",
          "istio_policy_status":"-",
          "method":"GET",
          "path":"/reviews/0",
          "protocol":"HTTP/1.1",
          "request_id":"15b2dffc-5f3f-4060-b9fa-898eab08****",
          "requested_server_name":"-",
          "response_code":"200",
          "response_flags":"-",
          "route_name":"-",
          "start_time":"2023-05-30T07:02:26.990Z",
          "trace_id":"18b3aed8af41****",
          "upstream_cluster":"outbound|9080|v2|reviews.default.svc.cluster.local",
          "upstream_host":"172.16.0.11:9080",
          "upstream_local_address":"172.16.0.252:44448",
          "upstream_service_time":"9",
          "upstream_transport_failure_reason":"-",
          "user_agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.X.X Safari/537.36",
          "x_forwarded_for":"-"
      }

      您可以在日誌中看到如下新增的日誌欄位。

      "fallback_path":"outbound|9080|v3|reviews.default.svc.cluster.local:outbound|9080|v2|reviews.default.svc.cluster.local"
      "fallback_final_cluster_name":"outbound|9080|v2|reviews.default.svc.cluster.local"
      "fallback_result":"fallback successful"

      通過日誌可以看到原本的路由目標是v3,因為v3下執行個體不可用,請求回退到v2版本。

步驟三:在帶有權重的路由下配置回退規則

  1. 執行以下命令,將reviews-v3版本置為可用狀態。

    kubectl scale deployment reviews-v3 --replicas=1
  2. 使用如下內容,建立reviews-route-fallback-sample2.yaml檔案,修改reviews-route的定義。

    apiVersion: networking.istio.io/v1beta1
    kind: VirtualService
    metadata:
      name: reviews-route
      namespace: default
    spec:
      hosts:
        - reviews 
      http:
        - route:
            - destination:
                host: reviews 
                subset: v3
              fallback:
                target:
                  host: reviews 
                  subset: v2
              weight: 50
            - destination:
                host: reviews 
                subset: v2
              fallback:
                target:
                  host: reviews 
                  subset: v1
              weight: 50
          retries:
            attempts: 0
  3. 執行以下命令,部署reviews新的路由和回退規則。

    kubectl apply -f reviews-route-fallback-sample1.yaml
  4. 在瀏覽器中訪問http://${YourGatewayIp}/productpage,並不斷重新整理頁面。

    可以看請求按50:50的比例落在reviews的v2和v3版本。為了讓顯示效果更明顯,本樣本關閉了重試。

  5. 執行以下命令,將v3的副本執行個體個數調整為0,驗證v3的回退規則是否符合預期。

    kubectl scale deployment reviews-v3 --replicas=0

    不斷重新整理productpage頁面,可以看到請求一直reviews的v2版本下,符合預期。

  6. 執行以下命令,將v2的副本執行個體數調整為0。

    kubectl scale deployment reviews-v2 --replicas=0

    不斷重新整理productpage頁面,可以看到類似如下頁面,productpage訪問reviews失敗。該頁面出現的機率為50%,另外50%的機率請求到了v2版本。因為v2版本不健康,實際請求回退到v1版本。productpage頁面..png

  7. 執行以下命令,查看日誌。

    kubectl logs -f  deployment/productpage-v1  -c istio-proxy --tail=10

    預期輸出:

    {
        "authority":"reviews:9080",
        "authority_for":"reviews:9080",
        "bytes_received":"0",
        "bytes_sent":"19",
        "downstream_local_address":"192.168.255.46:9080",
        "downstream_remote_address":"172.16.0.252:47738",
        "duration":"0",
        "fallback_path":"outbound|9080|v3|reviews.default.svc.cluster.local:outbound|9080|v2|reviews.default.svc.cluster.local",
        "fallback_final_cluster_name":"-",
        "fallback_result":"fallback cluster is unhealthy",
        "istio_policy_status":"-",
        "method":"GET",
        "path":"/reviews/0",
        "protocol":"HTTP/1.1",
        "request_id":"b207a764-b6d7-4ef8-bc71-59f264c3****",
        "requested_server_name":"-",
        "response_code":"503",
        "response_flags":"UH",
        "route_name":"-",
        "start_time":"2023-05-30T07:32:08.999Z",
        "trace_id":"a40c32a7b2cf****",
        "upstream_cluster":"outbound|9080|v3|reviews.default.svc.cluster.local",
        "upstream_host":"-",
        "upstream_local_address":"-",
        "upstream_service_time":"-",
        "upstream_transport_failure_reason":"-",
        "user_agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.X.X Safari/537.36",
        "x_forwarded_for":"-"
    }

    可以看到productpage-v1下有類似如上503日誌。基於reviews-route帶權重的路由配置,productpage會有50%的機率請求v3版本的reviews。由於v3版本不可用,Sidecar(istio-proxy) 基於回退規則,嘗試從v3回退到v2版本。由於v2版本不健康,請求發往了v3版本。您可以通過欄位"upstream_cluster":"outbound|9080|v3|reviews.default.svc.cluster.local"進行確認。