分布式系統存在高度複雜性的特點,在基礎設施、應用邏輯、營運流程等環節都可能存在穩定性風險而導致業務系統的失效。因此構建一個具有容錯能力的分布式系統非常重要。本文介紹如何通過ASM設定逾時、重試、隔板和熔斷機制構建分布式系統的容錯能力。
背景資訊
容錯能力是指系統在部分故障期間,仍然能夠繼續啟動並執行能力。建立一個可靠的彈性系統會對其中的所有服務提出容錯要求。雲環境的動態性質要求服務能預見這些失敗,並能優雅地響應意外情況。
任何一個服務都有可能存在請求失敗的情況,在請求失敗的情況下,能夠使用適當的後備操作非常重要。一個服務中斷可能會引起連鎖反應從而導致嚴重的業務後果,因此構建、運行和測試系統的彈效能力非常必要。ASM提供了逾時處理、重試機制、隔板模式和熔斷機制容錯解決方案,在不修改應用程式任何代碼的情況下為應用程式帶來了容錯能力。
逾時處理
原理介紹
當請求上遊服務的時候,存在上遊服務一直沒有響應的現象。您可以設定一個等待時間,到達一個等待時間後,如果上遊服務還是沒有響應,直接請求失敗,不再去等待上遊服務。
通過設定逾時,可以確保應用程式在後端服務無響應時可以收到錯誤返回,從而使其能夠以適當的回退行為進行處理。逾時更改的是發出請求的用戶端等待響應的時間,對目標服務的處理行為沒有影響。因此這並不意味著請求的操作失敗。
解決方案
ASM支援在虛擬服務中為路由設定逾時策略來更改逾時值,如果Sidecar代理在設定的時間內未收到響應,則該請求將失敗。通過這種方式調整逾時,所有使用路由的請求都將使用該逾時設定。
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: httpbin
spec:
hosts:
- 'httpbin'
http:
- route:
- destination:
host: httpbin
timeout: 5s
timeout:設定逾時時間,如果在設定的時間內請求的服務沒有響應,則直接返回錯誤結果,不再等待。
重試機制
原理介紹
如果某個服務要求另一個服務失敗,例如請求逾時、連線逾時、服務宕機等錯誤,您可以通過配置重試機制,重新請求該服務。
請勿頻繁地重試或重試過長時間,避免出現級聯的系統故障。
解決方案
ASM支援使用虛擬服務定義HTTP請求重試策略。以下樣本定義網格中的服務要求httpbin應用時,如果httpbin應用無響應或與httpbin應用建立串連失敗,會重新請求httpbin應用3次,每次的請求時間為5秒。
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: httpbin
spec:
hosts:
- 'httpbin'
http:
- route:
- destination:
host: httpbin
retries:
attempts: 3
perTryTimeout: 5s
retryOn: connect-failure,reset
您可以在retries結構中配置如下欄位,自訂Sidecar對請求進行重試的行為。
欄位 | 說明 |
attempts | 一個請求的最大重試次數。如果在配置重試機制的同時,為服務路由配置了逾時時間,則實際的重試次數取決於逾時時間的設定。例如,如果一次請求未達到最大重試次數,但所有重試花費的總時間已經超過了逾時時間,則Sidecar代理會停止請求重試並進行逾時返回。 |
perTryTimeout | 每次重試的逾時時間,單位為毫秒(ms)、秒(s)、分鐘(m)或小時(h)。 |
retryOn | 指定在何種條件下進行重試。多個重試條件需使用英文半形逗號(,)分隔。更多資訊,請參見常見的HTTP請求重試條件和常見的gRPC請求重試條件。 |
常見的HTTP請求重試條件如下:
重試條件 | 說明 |
connect-failure | 如果由於與上遊服務建立串連失敗(連線逾時等)導致請求失敗,進行重試。 |
refused-stream | 如果上遊服務返回REFUSED_STREAM幀來重設流,進行重試。 |
reset | 如果上遊服務未響應就發生了串連斷開、重設、讀取逾時事件,進行重試。 |
5xx | 如果上遊服務返回任何5XX的響應碼(例如500、503等),或上遊服務無響應,進行重試。 說明 5XX包含connect-failure和refused-stream的條件。 |
gateway-error | 當上遊服務返回502、503或504狀態代碼時,進行重試。 |
envoy-ratelimited | 當請求中存在x-envoy-ratelimited Header時,將進行重試。 |
retriable-4xx | 當上遊服務返回409狀態代碼時,進行重試。 |
retriable-status-codes | 當上遊服務返回的狀態代碼被判定為可以重試時,進行重試。 說明 您可以直接在retryOn欄位中加入合法的狀態代碼,這些狀態代碼將被判定為可以重試的狀態代碼。例如 |
retriable-headers | 當上遊服務返回的響應Header中包含可以重試的Header時,進行重試。 說明 您可以在發往上遊服務的請求中加入 |
gRPC請求基於HTTP/2,因此您也可以在HTTP請求重試策略的retryOn欄位中設定gRPC協議的重試條件。常見的gRPC請求重試條件如下:
重試條件 | 說明 |
cancelled | 如果上遊gRPC服務的回應標頭部中的gRPC狀態代碼為cancelled(1),進行重試。 |
unavailable | 如果上遊gRPC服務的回應標頭部中的gRPC狀態代碼為unavailable(14),進行重試。 |
deadline-exceeded | 如果上遊gRPC服務的回應標頭部中的gRPC狀態代碼為deadline-exceeded(4),進行重試。 |
internal | 如果上遊gRPC服務的回應標頭部中的gRPC狀態代碼為internal(13),進行重試。 |
resource-exhausted | 如果上遊gRPC服務的回應標頭部中的gRPC狀態代碼為resource-exhausted(8),進行重試。 |
配置預設HTTP請求重試策略
在預設情況下,即使不通過虛擬服務定義HTTP請求重試策略,網格內的服務在訪問其它HTTP服務時仍然會應用一個預設的HTTP請求重試策略。該預設重試策略的重試次數為2次,沒有重試逾時時間設定,重試條件預設為connect-failure、refused-stream、unavailable、cancelled和retriable-status-codes。您可以ASM控制台的基本資料頁面對預設的HTTP請求重試策略進行配置。配置後,新的HTTP請求重試策略將會覆蓋預設的重試策略。
該功能僅支援ASM執行個體為1.15.3.120及以上版本。關於升級執行個體的具體操作,請參見升級ASM執行個體。
登入ASM控制台,在左側導覽列,選擇 。
在網格管理頁面,單擊目標執行個體名稱,然後在左側導覽列,選擇 。
在基本資料頁面的配置資訊地區,單擊預設HTTP請求重試策略右側的編輯。
在預設HTTP請求重試策略對話方塊,配置相關資訊,然後單擊確定。
配置項
說明
重試次數
對應上文的attempts。在預設HTTP請求重試策略中,該欄位可以配置為0,表示預設禁用HTTP請求重試。
重試逾時
對應上文的perTryTimeout。
重試條件
對應上文的retryOn。
隔板模式
原理介紹
隔板模式指限制某個用戶端對目標服務的串連數、訪問請求數等,避免對一個服務的過量訪問,如果超過配置的閾值,則會斷開請求。隔板模式有助於隔離用於服務的資源,並避免級聯故障。其中,最大串連數和連線逾時時間是對TCP和HTTP都有效通用串連設定,而每個串連最大請求數和最大請求重試次數僅針對HTTP1.1、HTTP2、GRPC協議的串連生效。
解決方案
ASM支援通過目標規則設定隔板模式,以下目標規則定義了其他服務要求httpbin應用時,最大並發串連數限制為1,每個串連最大請求數為1,最大請求重試次數為1,並且不能在10秒內建立已連線的服務會得到503響應。
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
name: httpbin
spec:
host: httpbin
trafficPolicy:
connectionPool:
http:
http1MaxPendingRequests: 1
maxRequestsPerConnection: 1
tcp:
connectTimeout: 10s
maxConnections: 1
http1MaxPendingRequests:最大請求重試次數。
maxRequestsPerConnection:每個串連最大請求數。
connectTimeout:連線逾時時間。
maxConnections:最大串連數。
熔斷機制
原理介紹
熔斷機制指不會重複向無響應的服務發出請求,而是觀察在給定時間段內發生的故障數。如果錯誤率超過閾值,則熔斷器將斷開請求,並且所有後續請求都將失敗,直到熔斷器被關閉為止。
解決方案
ASM支援通過目標規則設定主機級熔斷機制,以下目標規則定義了如果其他服務要求httpbin應用時,在5秒內連續3次訪問失敗,則將在5分鐘內斷開請求。
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
name: httpbin
spec:
host: httpbin
trafficPolicy:
outlierDetection:
consecutiveErrors: 3
interval: 5s
baseEjectionTime: 5m
maxEjectionPercent: 100
consecutiveErrors:連續錯誤數量。
interval:驅逐檢測的時間間隔。
baseEjectionTime:最小的驅逐時間長度。
maxEjectionPercent:負載平衡池中允許被驅逐的主機的最大百分比。
查看主機級熔斷相關指標
和ASMCircuitBreaker不同,主機分級的熔斷機制下,用戶端的Sidecar代理會單獨檢測每個上遊服務主機的錯誤率,並在主機連續發生錯誤時將主機從服務的負載平衡池中驅逐。
主機級熔斷可以產生一系列相關指標,以協助判斷熔斷是否發生,部分指標的說明如下:
指標 | 指標類型 | 描述 |
envoy_cluster_outlier_detection_ejections_active | Gauge | 當前被驅逐的主機的數量。 |
envoy_cluster_outlier_detection_ejections_enforced_total | Counter | 發生主機被驅逐事件的次數。 |
envoy_cluster_outlier_detection_ejections_overflow | Counter | 因超過最大驅逐百分比而放棄驅逐主機的次數。 |
ejections_detected_consecutive_5xx | Counter | 檢測到主機連續產生5xx錯誤的次數。 |
您可以通過配置Sidecar代理的proxyStatsMatcher使Sidecar代理上報相關指標,然後使用Prometheus採集並查看熔斷相關指標。
通過proxyStatsMatcher配置Sidecar代理上報熔斷指標。在配置proxyStatsMatcher時,選中正則匹配,配置為
.*outlier_detection.*
。具體操作,請參見proxyStatsMatcher。重新部署httpbin無狀態工作負載。具體操作,請參見重新部署工作負載。
配置主機級熔斷指標採集及警示
配置完成上報主機分級的熔斷指標後,您可以配置採集相關指標到Prometheus,並基於關鍵計量配置警示規則,實現熔斷髮生時的及時警示。以下以可觀測監控Prometheus版為例說明如何配置主機級熔斷指標採集和警示。
在可觀測監控Prometheus版中,為資料面叢集接入阿里雲ASM組件或升級至最新版,以保證可觀測監控Prometheus版可以採集到暴露的熔斷指標。有關更新接入組件的具體操作,參考接入組件管理。(如果參考整合自建Prometheus實現網格監控配置了通過自建Prometheus採集服務網格指標,則無需操作。)
建立針對主機級熔斷的警示規則。具體操作,請參見通過自訂PromQL建立Prometheus警示規則。配置警示規則的關鍵參數的填寫樣本如下,其餘參數可參考上述文檔根據自身需求填寫。
參數
樣本
說明
自訂PromQL語句
(sum (envoy_cluster_outlier_detection_ejections_active) by (cluster_name, namespace)) > 0
樣本通過查詢envoy_cluster_outlier_detection_ejections_active指標來判斷當前叢集中是否有正在被驅逐的主機,並將查詢結果按照服務所在命名空間和服務名稱進行分組。
警示內容
觸發級熔斷,有工作負載連續發生錯誤,從服務負載平衡池中被驅逐!命名空間:{{$labels.namespace}},驅逐發生的服務:{{$labels.cluster_name}}。驅逐數量:{{ $value }}
樣本的警示資訊展示了觸發熔斷的服務所在命名空間以及服務名稱,以及當前該服務被驅逐的數量。