雪崩:一個微小的故障引起系統其他部分出現故障,最終使整個系統不可用。
雪崩一般經歷以下三個階段:
- 實例能力出現過載。可能是 bug 導致性能下降,可能是實例宕機,可能是突發流量,總之實例無法處理如此多請求。
- 服務資源耗盡不可用。過載后,大量請求積壓在實例中,迅速消耗服務的CPU,內存,線程等資源。這些資源耗盡,實例出現超時和崩潰。表現為不可用。負載均衡器將請求調度到其他實例,其他實例也同樣過載不可用。服務過載。
- 一個服務不可用,服務調用方也出現大量積壓請求,同樣出現過載。逆向沿著調用鏈路傳播,最終導致系統雪崩。
解決思路:
- 熔斷。調用方認為被調用服務過載,則快速返回錯誤,不執行調用。
- 限流。調用方限定請求量,避免過載。
- 降級。犧牲非核心業務保護核心業務。
- 擴容。增加實例,提升資源。
Sentinel
Sentinel 是服務容錯插件。實現流量控制,熔斷降級,系統保護等多個功能。
Sentinel 將被保護對象稱為資源。資源可以是接口,URI,代碼。
外部請求訪問資源時,Sentinel 將外部請求包裝為 Entry 對象,并交給 slot chain 處理。
slot chain 是典型的責任鏈模式。
常見的 slot 有:
NodeSelectorSlot構建請求的訪問路徑,并且串聯調用鏈。
StatisticSlot統計運行期數據,比如接口響應時間,線程數,QPS等。
DegradeSlot判定是否熔斷降級。FlowSlot判定限流。
實現ProcessorSlot接口可以自定義slot。
sentinel 流量控制模式:
- 直接流控。當前資源訪問壓力超出閾值,則限制請求。
- 關聯流控。關聯資源訪問壓力超出閾值,則限制請求。如果資源A與資源B爭搶資源,比如數據庫。而資源A優先級低。如果A的關聯資源(B)的訪問壓力超出閾值,則限制A的請求,把數據庫資源讓給B。
- 鏈路流控。如果兩個接口(/api/name, /api/overview)都能訪問資源。而只想限流其中一個接口。
sentinel 流量控制策略:
- 快速失敗。
- warm up。隨時間增加流量閾值。
- 排隊等待。請求進入等待隊列,在等待隊列中超時則失敗。
@SentinelResource注解的blockHandler屬性指定降級方法的名稱,它僅在 BlockException 情況下觸發。BlockException 是 sentinel 定義的異常類,表示被 slot chain 攔截。對于其他 RuntimeException,需要用 fallback 屬性指定降級方法。
sentinel 提供三種熔斷規則:
- 異常比例。
- 異常數。
- 慢調用比例。