全部產品
Search
文件中心

Alibaba Cloud Service Mesh:Service Mesh中常見的503報錯

更新時間:Jun 30, 2024

本文介紹Service Mesh中常見的503報錯情境及解決方案。

偶發503

情境一:使用自訂監控指標功能進行個人化配置,每當配置變更時,日誌監控發現少量請求出現503

問題原因

自訂指標功能的邏輯是通過產生一個對應的EnvoyFiter來進行istio.stats的配置更新。該配置在Envoy Listener層級生效,即通過LDS同步生效。Envoy在應用Listener層級的配置時,需要斷開已有串連。對應的在途請求因為串連被Reset或Close導致出現503。

解決方案

上遊Server主動Close串連時,您看到的503並非上遊Server發送,而是用戶端Sidecar因為上遊串連主動斷開,由本地返回的響應。

Istio預設的重試配置中未包含“上遊Server主動Close串連”的情況。EnvoyProxy的重試條件中,Reset符合這種情況對應的觸發條件。因此,您需要為對應服務的路由配置retry Policy。在VirtualService下的retry Policy配置包含Reset的觸發條件。

配置樣本如下。該配置僅針對Ratings服務生效。

apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: ratings-route
spec:
  hosts:
  - ratings.prod.svc.cluster.local
  http:
  - route:
    - destination:
        host: ratings.prod.svc.cluster.local
        subset: v1
    retries:
      attempts: 2
      retryOn: connect-failure,refused-stream,unavailable,cancelled,retriable-status-codes,reset,503

相關FAQ

為什麼Istio預設的重試機制未生效?

Istio預設重試發生的條件如下。預設會重試2次。該情境未在重試條件內,因此未生效。

           "retry_policy": {
            "retry_on": "connect-failure,refused-stream,unavailable,cancelled,retriable-status-codes",
            "num_retries": 2,
            "retry_host_predicate": [
             {
              "name": "envoy.retry_host_predicates.previous_hosts"
             }
            ],
            "host_selection_retry_max_attempts": "5",
            "retriable_status_codes": [
             503
            ]
           }
  • connect-failure:串連失敗。

  • refused-stream:當HTTP2 Stream流返回REFUSED_STREAM錯誤碼

  • unavailable:當gRPC請求返回unavailable錯誤碼。

  • cancelled:當gRPC請求返回cancelled錯誤碼。

  • retriable-status-codes:當請求返回的status_coderetriable_status_codes配置下定義的錯誤碼匹配。

關於最新版本的EnvoyProxy完整的重試條件,請參見以下文檔。

情境二:偶發503,沒有規律,在此過程中並未發生配置變更

503偶爾出現,但是在流量密集時,會持續出現。通常出現在Sidecar的Inbound側。

問題原因

Envoy的空閑串連保持時間和應用不匹配。Envoy空閑連線時間預設為1小時。

  • Envoy空閑連線時間過長,應用相對較短:

    應用已經結束空閑串連,但是Envoy認為沒有結束。此時如果有新的串連,就會報503UC。Dingtalk_20230510151540..png

  • Envoy空閑連線時間過短,應用相對較長:

    這種情況不會導致503。Envoy認為之前的串連已經被關閉,因此會直接建立一個串連。Dingtalk_20230510151639..png

解決方案

方案一:在DestinationRule中配置idleTimeout

造成該問題的原因就是idleTimeout不匹配,因此在DestinationRule中配置idleTimeout屬於比較根本的解決辦法。

如果配置了idelTimeout,在Outbound和Inbound兩側都會生效,即Outbound和Inbound的Sidecar都會存在idleTimeout的配置。如果用戶端沒有Sidecar,idleTimeout也會生效,並能夠有效減少503。

配置建議:此配置與業務相關,太短會導致串連數過高。建議您配置為略短於業務應用真正的idleTimeout時間。

方案二:在VirtualService中配置重試

重試會重建串連,可以解決此問題。具體操作,請參見情境一的解決方案。

重要

該操作為非等冪的請求,重試存在較大的風險,請謹慎操作。

情境三:Sidecar生命週期相關

問題原因

Sidecar和業務容器生命週期導致,常發生於Pod重啟。

解決方案

具體操作,請參見Sidecar生命週期

必定503

情境一:應用監聽localhost

問題原因

當叢集中的應用監聽localhost網路地址時,如果localhost是本地地址,會導致叢集中的其他Pod無法對其進行正常訪問。

解決方案

您可以通過對外暴露應用服務解決此問題。具體操作,請參見如何使叢集中監聽localhost的應用被其他Pod訪問

情境二:啟用Sidecar後,健全狀態檢查總是失敗,報錯503

問題原因

Service Mesh開啟mTLS後,kubelet向Pod發送的健全狀態檢查請求被Sidecar攔截,而kubelet沒有對應的TLS認證,導致健全狀態檢查失敗。

解決方案

您可以通過配置連接埠健全狀態檢查流量免於經過Sidecar代理解決此問題。具體操作,請參見為什麼注入Sidecar後,健全狀態檢查總失敗或者無效