熔斷是當某個服務調用慢或者有大量超時現象(過載),系統停止後續針對該服務的調用而直接返回,直至情況好轉才恢復調用。這通常是為防止造成整個系統故障而採取的一種保護措施,也稱過載保護。很多時候剛開始,可能只是出現了局部小規模系統故障,但後來故障影響的範圍越來越大,最終導致了全局性的後果。 ...
熔斷
當某個服務調用慢或者有大量超時現象(過載),系統停止後續針對該服務的調用而直接返回,直至情況好轉才恢復調用。這通常是為防止造成整個系統故障而採取的一種保護措施,也稱過載保護。很多時候剛開始,可能只是出現了局部小規模系統故障,但後來故障影響的範圍越來越大,最終導致了全局性的後果。
限流
對某個服務調用設置最高QPS閾值,高於閾值的請求放棄調用直接返回。這種模式不能解決服務依賴的問題,只能解決系統整體資源分配問題,因為沒有被限流的請求依然有可能造成雪崩效應。
限流處理方案:
- 限制最大併發數;
- 限制時間窗內最大請求數;
- 令牌桶演算法。該演算法描述如下:
1)限制用戶平均發送速率為r 位元組/s,則以r 個/s的速度往桶中放入令牌,即為每一個位元組配備一個令牌。
2)假設桶的最大容量為b,如果令牌桶已滿,則丟棄這個令牌。
3)當流入速率為v 位元組/s,則從桶中取令牌的速率為v 個/s。拿到令牌的流量通過,拿不到的則執行限制邏輯。該演算法具有如下特點:
1)長期來看,流入速率受令牌添加速率的影響,被穩定為r。 2)令牌桶有一定的容量,可以抵擋一定的流量突發情況。 3)假設最大流入速率為M,則 M > r。
4)假設能承受最大流入速率M的持續時間為T,則 T = b / (M - r)。
5)假設最大流入速率M持續時間內傳輸的流量為B,則 B = T * M。
6)當一個n個位元組大小的請求數據包到達,將從桶中刪除n個令牌。但如果桶中餘下令牌不足n個,
則不會刪除令牌,該請求將被限流(要麼丟棄,要麼緩衝區等待)。
7)當r極大,如r > 1000時,也就是勻速放一個令牌的時間間隔是小於1 ms的,這個精度不好控制;
但可以採用流入事件觸發方式來添加令牌,即下一個請求到來會先計算當前時間到上一次添加令
牌時間這個時間段內應該添加的令牌數(取整數部分),然後添加完令牌再決定通過或限制當前請求,
這樣依然可以維持整體流入速率穩定在r。該演算法具有的優點:
1)流量比較平滑,並且可以抵擋一定的流量突發情況。
- 漏桶演算法。漏桶作為計量工具,可用於流量整形(Traffic Shaping)和流量控制(Traffic Policing)。該演算法描述如下:
1)一個固定容量的漏桶,以恆定的速率流出。 2)如果漏桶是空的,則不需流出。 3)如果流入超出了漏桶的容量,則溢出(被丟棄)。
該演算法具有的優點:
1)該演算法可平滑突發流量,是消滅突髮狀況的有效堅決辦法。
限流可以在應用層實現,也可以在接入層實現,通常使用redis + lua或者nginx + lua來實現。
降級
當訪問量劇增致服務出現問題(如響應時間慢或不響應),或非核心服務影響到核心流程的性能時,仍要保證服務是可用的;即使是有損的,且有些服務是無法降級的,如加入購物車、結算等。降級可以是自動降級或人工降級,可以是讀服務降級或寫服務降級,還可以是多級降級。自動降級可根據系統負載、資源使用情況、調用超時、失敗重試次數、故障、限流閥值、SLA(Service-Level Agreement)等指標進行降級。
降級處理方案:
- 返回預設值:比如庫存調用超時,返回預設現貨;
- 返回兜底數據:通常是異常或錯誤發生時最後適用的數據,比如預備的靜態頁面、預設的數據;
- 返回緩存數據;
- 返回空值;
- 放棄調用。
降級發生場景:
- 讀降級:多級緩存模式下,如接入層緩存-->應用層緩存-->分散式緩存(Redis Clusters)-->RPC / DB,可由遠及近的順序降級讀緩存,這種方式適用於對讀一致性要求不高的場景。另外,也可走靜態頁,或屏蔽讀;
- 寫降級:只更新Cache,之後非同步扣減庫存到DB,保證最終一致性即可。
在大促活動期間,對某些占用了稀缺資源的次要頁面或片段調用降級,同時也對爬蟲返回靜態頁或者空數據,以保證核心業務正常開展。
隔離
下圖展示了非隔離狀態下單個用戶請求被服務依賴I阻塞的情況:
下圖展示了非隔離狀態下服務依賴I阻塞了全部用戶請求,而其他用戶請求此時根本沒有機會接受線程池的處理:
對請求按類型劃分並分配不同數量的線程池來隔離處理,各自互不影響。當某個請求類型的線程池資源耗盡,則後續該類型請求可停止處理而直接返回,不影響其他請求類型線程的正常執行;這就避免了,非隔離狀態下慢服務阻塞所有用戶請求導致整個線程池處理能力下降。
Hystrix 是一個解決分散式系統交互超時處理和容錯的類庫,是 Netflix 的眾多開源項目之一。Hystrix 採用線程池和信號量兩種隔離方式,來限制併發訪問量和故障擴散。
緩存
記憶體緩存通常用來加DB速數據訪問,但記憶體緩存在大面積失效或負載過大或重啟之後,導致數據訪問穿透到DB,依然可能引起雪崩效應的發生;靜態緩存省去了服務端對動態內容的處理過程,又縮短了與用戶之間的距離,能快速響應用戶的請求。