一般介面都有乙個最大處理能力,比如每秒處理n萬個請求。正常情況下,在前端允許的時延內,後端介面都能處理完請求。但到了類似搶購小公尺神機的場景下,後端的介面一般會承受超出平時請求量幾十幾百甚至幾萬倍的請求量,而且這寫請求全部集中在一段時間內,稱之為過載時間。這段時間內,後端介面的處理能力達到了極限,不停的拼命做都取不完緩衝區的請求,因為此時緩衝區的資料一直在不停累積,進入到緩衝區沒有及時處理的請求,對外表現為系統繁忙、超時、沒有響應;而沒有進入到快取區的資料就被丟棄,對外反應就是失敗。所以可以看到,一般的搶購系統都處於長期失敗或者繁忙狀態。
良好的介面服務應該在有限的資源內提供有限的處理能力,良好的系統設計要能夠及時發現超出介面處理能力的請求,及時阻斷丟棄,而良好的前端展示應該給與使用者友好的提示,使用進度條,動畫等描述系統繁忙的場景,減少使用者反感,同時要嚴格限制使用者重試的頻率。中間處理模組到後端介面的重試處理也要有時間和頻率限制。
對介面服務來說,防止雪崩的方法一般有三種:
1、頻率限制
在介面入口處,甚至系統的入口處應該設定頻率限制,為介面設定單位時間內最大的處理量,同時記錄單位時間內已經處理的請求量,當請求量大於最大處理量的時候,直接拒絕外部的請求,保護內部系統的心臟承受能力。
2、超時丟棄
這裡的超時是指請求從進入接收快取區到介面從快取區取出請求準備處理的時間超過了一定閾值(比如前端超時時間)。如果發生超時,則說明就算處理了取出的資料,前端也已經超時了,後端介面做的就是無用功,倒不如就在這裡一次性丟棄。這裡的快取區指的是核心快取區。
標記進入快取區時間的方法可以有2種:
(1)、直接利用ioctl函式的siocgstamp命令。在初始化socket的時候和取資料的時候分別呼叫一次,第一次是設定,第二次是獲取資料進入快取區的時間。另外還可以用recvmsg/sendmsg函式通過設定socket的so_timestamp引數來獲取請求進入網絡卡的時間。
(2)、在介面和快取區之間搭建一層inte***ce
程序只負責從快取區讀取資料打上時間戳放入供介面呼叫的channel中,實際業務處理介面則從channel中獲取請求,同時獲取時間戳。由於inte***ce
程序只負責取資料,所以效率較高,打上的時間戳可以近似認為就是請求進入快取區的時間。
3、修改socket快取區大小
根據介面處理能力和前端超時時間來設定socket快取區大小,這樣的話利用socket快取區充當佇列,超過佇列長度的請求就直接被丟棄了,這樣也可以防止系統雪崩。只是對使用者不那麼友好。有人給出的參考計算式:緩衝區大小
=(前端超時時間
-請求處理時間
-前端網路延時*2)
*(每秒最大處理請求數
/1000)*
請求包大小。
如果系統處在過載處理時間段內,對每個請求比較超時時間也會占用一定系統資源,對於高效能的服務來說這塊的影響也不能小視,所以如果能對第一次因為過載和丟棄的請求之後的請求包進行一定量的丟棄處理,可以有效減少這部分的計算資源,減輕系統的負載,使得業務能夠快速恢復。
防止雪崩涉及到整個業務的方方面面,不是單一後端服務做好就可以解決的。這裡再附上專家們總結的經驗以備後用。
1、每個系統,自己的最大處理能力是多少要做到清清楚楚。
2、每個系統要做好自我保護,量力而為,而不是盡力而為。對於超出自己處理能力範圍的請求,要勇於拒絕。
3、每個系統要有能力發現哪些是有效的請求,哪些是無效的請求。上面兩個案例中,過載的系統都不具備這中慧眼,逮著請求做死的處理,雪球時其實是做無用功。
4、前端系統有保護後端系統的義務,sla中承諾多大的能力,就只給到後端多大的壓力。這就要求每乙個前後端介面的地方,都有明確的負載約定,一環扣一環。
5、當過載發生時,該拒絕的請求(1、超出整個系統處理能力範圍的;2、已經超時的無效請求)越早拒絕越好。就像上海機場到市區的高速上,剛出機場就有電子公示牌顯示,進入市區某某路段擁堵,請繞行。
6、對於使用者的重試行為,要適當的延緩。例如登入發現後端響應失敗,再重新展現登入頁面前,可以適當延時幾秒鐘,並展現進度條等友好介面。當多次重試還失敗的情況下,要安撫使用者。
7、產品特性設計和發布上,要盡量避免某個時刻導致大量使用者集體觸發某些請求的設計。發布的時候注意灰度。
8、中間層server對後端傳送請求,重試機制要慎用,一定要用的話要有嚴格頻率控制。
9、當雪球發生了,直接清空雪球佇列(例如重啟程序可以清空socket 緩衝區)可能是快速恢復的有效方法。
10、過載保護很重要的一點,不是說要加強系統效能、容量,成功應答所有請求,而是保證在高壓下,系統的服務能力不要陡降到0,而是頑強的對外展現最大有效處理能力。
保護腰帶一些方法
脊柱外科學專家告誡人們 久坐傷腰!長期坐位工作,使腰背肌長期處於緊張狀態,從而出現痙攣 缺血 水腫 粘連,腰背肌無力,甚至疼痛。有人測量了一位35歲婦女的腰3 4椎間盤在各種體位下的壓力承擔 躺下時為3.5千克 平方厘公尺 站立時為9.6千克 平方厘公尺 坐位時竟高達15.3千克 平方厘公尺。可見坐...
服務類程式防止記憶體不斷增長的一些方法 一)
相信在日常開發中,大家經常會碰到編寫服務類程式記憶體不斷增長的情況。我用我這些日子開發服務類程式的經驗給大家做個總結。1.單例模式 單例模式對於某些高復用的應用,能極大的節省記憶體開銷,是個不錯的設計方案。2.對於繼承了idisposable 介面的物件,盡量使用using gc 會在大括號結束後對...
函式過載的一些問題
面試問題 void fun int,double void fun double,int 現在呼叫fun int int 會怎麼樣?函式過載的匹配過程有三步 1 確定候選函式,兩個原則 1 函式名相同 2 在呼叫點函式可見。顯然對於該題目來說兩個函式都是候選函式。2 確定可行函式,也是有兩個原則 1...