如何處理暫時性故障?

在服務網格中使用 Envoy 的最大優勢之一,是它讓服務從實作複雜的彈性功能中解放出來,例如斷路、離群值偵測和重試,這些功能使服務能夠在諸如滾動升級、動態基礎架構和網路故障等現實情況下保持彈性。在 Envoy 中實作這些功能不僅提高了服務的可用性和彈性,還在行為和可觀察性方面帶來了一致性。

本節將概略說明 Envoy 支援的組態,以及如何將這些功能結合使用來處理這些情境。

斷路

斷路是分散式系統的關鍵組件。斷路讓應用程式設定故障臨界值,以確保安全的最大值,允許元件快速失敗並儘快施加背壓。套用正確的斷路臨界值有助於節省資源,否則這些資源會浪費在等待請求(逾時)或不必要地重試請求上。Envoy 中斷路實作的主要優勢之一,是斷路限制是在網路層級套用的。

重試

自動請求重試是確保服務彈性的另一種方法。請求重試通常應用於防範暫時性故障。Envoy 支援非常豐富的可設定參數,可決定重試的請求類型、請求應重試的次數、重試的逾時等。

gRPC 服務中的重試

對於 gRPC 服務,Envoy 會查看回應中的 gRPC 狀態,並根據 x-envoy-retry-grpc-on 中設定的狀態嘗試重試。

下列 gRPC 中的應用程式狀態代碼被認為是可安全自動重試的。

  • CANCELLED - 如果服務中有錯誤可以重試,則傳回此代碼。

  • RESOURCE_EXHAUSTED - 如果服務所依賴的某些資源在該實例中已耗盡,則傳回此代碼,以便重試另一個實例會有幫助。請注意,對於共用資源耗盡,傳回此代碼沒有幫助。相反,應使用 速率限制來處理這種情況。

HTTP 狀態代碼 502 (Bad Gateway)503 (Service Unavailable)504 (Gateway Timeout) 都會對應到 gRPC 狀態代碼 UNAVAILABLE。這也被認為是可安全自動重試的。

在設定重試時,請求的冪等性是一個重要的考量因素。

Envoy 也支援對其重試策略的擴充功能。重試外掛程式允許您自訂 Envoy 重試實作以符合您的應用程式。

離群值偵測

離群值偵測是一種動態偵測上游叢集中行為不當的主機的方法。透過偵測這類主機並將其從健康的負載平衡集中暫時移除,Envoy 可以提高叢集的成功率。Envoy 支援根據連續的 5xx、連續的閘道故障和成功率來設定離群值偵測。

Envoy 也允許您設定移除時間。

組態

下列設定有助於最佳化一些組合,例如

  • 常見情境(即滾動升級)的最大請求成功率

  • 速度

  • 避免級聯故障

斷路器

{
   "thresholds": [
     {
       "max_retries": 10,
     }
  ]
}

針對此特定使用案例,應設定上游叢集的重試預算,以啟用和控制並行的重試。如果設定的值太低,則某些請求將不會重試,這可以透過 upstream_rq_retry_overflow 來測量。如果設定的值太高,則服務可能會被重試請求淹沒。

離群值偵測

{
   "consecutive_5xx": 5,
   "base_ejection_time": "30s",
   "max_ejection_percent": 50,
   "consecutive_gateway_failure": 5,
}

如果連續發生 5 次 5xx閘道故障,此設定會啟用離群值偵測,並將移除的主機數量限制為上游叢集大小的 50%。此組態對移除的主機數量設定了安全限制。請注意,一旦主機被移除,它將在經過一段移除時間後返回集區(等於 base_ejection_time 乘以主機被移除的次數)。

請求重試

{
   "retry_on": "cancelled,connect-failure,gateway-error,refused-stream,reset,reset-before-request,resource-exhausted,unavailable",
   "num_retries": 1,
   "retry_host_predicate": [
   {
      "name": "envoy.retry_host_predicates.previous_hosts"
   }
  ],
  "host_selection_retry_max_attempts": "5"
}

請求將根據 retry_on 中記載的條件進行重試。此設定也將 Envoy 設定為使用 先前主機重試謂詞,使其能夠選擇與先前請求失敗的主機不同的主機,因為通常在同一個主機上的故障可能會持續一段時間,而立即重試成功的機率較小。