如何處理暫時性故障?
在服務網格中使用 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 設定為使用 先前主機重試謂詞,使其能夠選擇與先前請求失敗的主機不同的主機,因為通常在同一個主機上的故障可能會持續一段時間,而立即重試成功的機率較小。