天天看點

億級流量架構服務降級,寫得太好了!

什麼是服務降級

如果看過我前面對服務限流的分析,了解服務降級就很容易了,對于一個景區,平時随便進出,但是一到春節或者十一國慶這種情況客流量激增,那麼景區會限制同時進去的人數,這叫限流,那麼什麼是服務降級呢?

簡單來說就是,将一些不太重要的景區項目砍掉,平時就那麼三五八個人,景區可以開放湖中遊泳啦,摸魚啦,捉蝦啦,有情況從業人員可以下湖撈你,但是現在客流量大了,從業人員關注不過來,都在湖裡晃蕩萬一沉了不太安全,大手一揮,這個項目砍了,将從業人員配置設定在其他地方。

在網際網路中也有類似的降級措施,像之前雙11, 有段時間是隻允許下單不允許退單或者改單,這樣做目的是什麼呢?

還是為了保證服務的可用性,當硬體軟體優化到一定的程度還是有上限,這時候将資源重點傾斜給核心業務,那些不太重要的就砍掉,保證服務的可用性。

服務等級定義

服務等級定義 SLA(Service Level Agreement)是判定壓測是否異常的重要依據。壓測過程中,通過監控核心服務狀态的 SLA 名額資料,可以更直覺地了解壓測業務的狀态。

SLA則是服務商與您達成的正常運作時間保證。

關于這個的詳細解釋,可以參考阿裡雲的介紹:服務等級定義SLA(

https://help.aliyun.com/document_detail/111729.html

),這兒不過多描述,SLA 分為網絡服務和雲服務,提供商的線上保證率通常要求達到6個9。

6個9含義

6個9指99.9999%,也就是一個服務有99.9999%機率是安全的,6個9有多安全呢?

2個9 = (1-99%)X24 X 365 = 87.6 小時 = 3.65天

3個9 = (1-99.9%)X24 X 365 = 8.76 小時

4個9 = (1-99.99%)X24 X 365 = 0.876 小時 = 52.56分鐘

5個9 = (1-99.999%)X24 X 365 = 0.0876 小時 = 5.256分鐘

6個9 = (1-99.9999%)X24 X 365 = 0.00876 小時 = 0.5256分鐘 = 31秒

也就是,一年當中,6個9的安全性最多會有31s服務是不可用,相對來說是極高的。

降級處理

兜底資料

這方面有很多例子,比如某些頁面挂了會傳回尋親子網。可以對一些關鍵資料設定一些兜底資料,例如設定預設值、靜态值、設定緩存等。

預設值: 設定安全的預設值,不會引起資料問題的值,比如庫存為0

靜态值:請求的頁面或api無法傳回資料,提供一套靜态資料展示,比如加載失敗提示重試,或者尋親子網,或者跳到預設菜單,給使用者一個稍微好一點的體驗。

緩存: 緩存無法更新便使用舊的緩存

限流降級

限流顧名思義,提前對各個類型的請求設定最高的QPS門檻值,若高于設定的門檻值則對該請求直接傳回,不再調用後續資源,也就是當流量洪峰到達的時候,可能需要丢棄一部分使用者來保證服務可用性,對于丢棄的使用者可以提供友好的提示,比如提示使用者目前繁忙、稍後重試等。

限流需要結合壓測等,了解系統的最高水位,也是在實際開發中應用最多的一種穩定性保障手段。當伺服器壓力劇增的情況下,根據目前業務情況及流量對一些服務和頁面有政策的降級,以此釋放伺服器資源以保證核心任務的正常運作。

逾時降級

對調用的資料設定逾時時間,當調用失敗時,對服務降級,舉個例子,當通路資料已經逾時了,且這個業務不是核心業務,可以在逾時之後進行降級,比如商品詳情頁上有推薦内容或者評價,但是可以降級顯示評價暫時不顯示,這對主要的使用者功能——購物,不産生影響,如果是遠端調用,則可以商量一個雙方都可以接受的最大響應時間,逾時則自動降級。

故障降級

如果遠端調用的伺服器挂了(網絡故障、DNS故障、HTTP服務傳回錯誤),則可以進行降級, 例如傳回預設值或者兜底資料或者靜态頁面,也可以傳回之前的緩存資料。

重試/自動處理

用戶端高可用:提供多個可調用的服務位址,這樣做

微服務重試:dubbo重試機制

API調用重試:當達到重試次數後,增加通路标記,服務降級,異步探測服務是否恢複。

WEB端:在服務不可用時,web端增加重試按鈕或自動重試可以提供更友好的體驗。

自動重試需設定重試次數和資料幂等處理

降級開關

在伺服器提供支援期間, 如果監控到線上一些服務存在問題,這個時候需要暫時将這些服務去掉,有時候通過服務調用一些服務,但是服務依賴的資料庫可能存在,網卡被打滿了,資料庫挂了,很多慢查詢等等,此時要做的就是暫停相關的系統服務,也就是人工使用開關降級。開關可以放在某地,定期同步開關資料,通過判斷開關值來決定是否做出降級。

開關降級還有一個作用,例如新的服務版本剛開發處在灰階測試階段,不太确定裡面的邏輯等等是否正确,如果有問題應該可以根據開關的值切回舊的版本。

在服務調用方設定一個flag,标記服務是否可用,另外key可以存儲存儲在在本地,也可以存儲在第三方的配置檔案中,例如資料庫、redis、zookeeper中。

爬蟲和機器人

分析機器人行為:短時間連續操作,agent,行為軌迹、拖拽(模拟登陸/秒殺/灌水)

爬蟲:引到到靜态頁或緩存頁

讀降級

簡而言之,在一個請求内,多級緩存架構下,後端緩存或db不可用,可以使用前端緩存或兜底資料讓使用者體驗好一點。

對于讀服務降級一般采用的政策有: 暫時切換讀: 降級到讀緩存、降級到走靜态化 暫時屏蔽讀: 屏蔽讀入口、屏蔽某個讀服務

通常讀的流程為: 接入層緩存→應用層本地緩存→分布式緩存→RPC服務/DB

我們會在接入層、應用層設定開關,當分布式緩存、RPC服務/DB有問題時自動降級為不調用。當然這種情況适用于對讀一緻性要求不高的場景。

頁面降級、頁面片段降級、頁面異步請求降級都是讀服務降級,目的是丢卒保帥,保護核心線程,或者因資料問題暫時屏蔽。

還有一種是頁面靜态化場景。

動态化降級為靜态化:比如,平時網站可以走動态化渲染商品詳情頁,但是,到了大促來臨之際可以将其切換為靜态化來減少對核心資源的占用,而且可以提升性能。其他還有如清單頁、首頁、頻道頁都可以這麼處理。可以通過一個程式定期推送靜态頁到緩存或者生成到磁盤,出問題時直接切過去。

靜态化降級為動态化:比如,當使用靜态化來實作商品詳情頁架構時,平時使用靜态化來提供服務,但是,因為特殊原因靜态化頁面有問題了,需要暫時切換回動态化來保證服務正确性。以上都保證了出問題時有預案,使用者可以繼續使用網站,不影響使用者購物體驗。

寫降級

大家都知道硬碟性能比不上記憶體性能,如果通路量很高的話,資料庫頻繁讀寫可能撐不住,那麼怎麼辦呢,可以讓記憶體(假如是Redis)庫來暫時滿足寫任務,同時将執行的指令記錄下來,然後将這個資訊發送到資料庫,也就是不在追求記憶體與資料庫資料的強一緻性,隻要資料庫資料與Redis資料庫中的資訊滿足最終話一緻性即可。

也就是說,正常情況下可以同步扣減庫存,在性能扛不住時,降級為異步。另外,如果是秒殺場景可以直接降級為異步,進而保護系統。還有,如下單操作可以在大促時暫時降級,将下單資料寫入Redis,然後等峰值過去了再同步回DB,當然也有更好的解決方案,但是更複雜,不是本篇的重點。

還有如使用者評價,如果評價量太大,那麼也可以把評價從同步寫降級為異步寫。當然也可以對評價按鈕進行按比例開放(比如,一些人看不到評價操作按鈕)。比如,評價成功後會發一些獎勵,在必要的時候降級同步到異步。

總結 在cap原理和BASE理論中寫操作存在于資料一緻性這個環節,降級的目的是為了提供高可用性,在多數的網際網路架構中,可用性是大于資料一緻性的。是以喪失寫入資料同步,通過上面的理論,我們也能勉強接受資料最終一緻性。高并發場景下,寫入操作無法及時到達或抗壓,可以異步消費資料/cache更新/log等方式

前端降級

當系統出現問題的時候,盡量将請求隔離在離使用者最近的位置,避免無效鍊路通路, 在後端服務部分或完全不可用的時候,可以使用本地緩存或兜底資料,在一些特殊場景下,對資料一緻性要求不高的時候,比如秒殺、抽獎等可以做假資料。

JS降級

在js中埋降級開關,在通路不到達,系統門檻值的時候可以避免發送請求

主要控制頁面功能的降級,在頁面中,通過JS腳本部署功能降級開關,在适當時機開啟/關閉開關。

接入層降級

可以在接入層,在使用者請求還沒到達服務的時候,通過、Nginx + Lua、Haproxy + lua過濾無效請求達到服務降級的目的, 主要控制請求入口的降級,請求進入後,會首先進入接入層,在接入層可以配置功能降級開關,可以根據實際情況進行自動/人工降級。這個可以參考第17章,尤其在後端應用服務出問題時,通過接入層降級進而給應用服務有足夠的時間恢複服務。

應用層降級

主要控制業務的降級,在應用中配置相應的功能開關,根據實際業務情況進行自動/人工降級。

SpringCloud中可以通過Hystrix配置中心可以進行人工降級,也可以根據服務的逾時時間進行自動降級, Hystrix是Netflix開源的一款針對分布式系統的延遲和容錯庫,目的是用來隔離分布式服務故障。

它提供線程和信号量隔離,以減少不同服務之間資源競争帶來的互相影響;官網講Hystrix提供優雅降級機制;提供熔斷機制使得服務可以快速失敗,而不是一直阻塞等待服務響應,并能從中快速恢複。Hystrix通過這些機制來阻止級聯失敗并保證系統彈性、可用。下圖是一個典型的分布式服務實作。

億級流量架構服務降級,寫得太好了!

片段降級

例如打開淘寶首頁,這一瞬間需要加載很多資料,有靜态的例如圖檔、CSS、JS等,也有很多其他商品等等,這麼多資料中,如果一部分沒有請求到,那麼就可以片段降級,意思是就不加載這些資料了,用其他資料頂替,例如其他商品資訊或者等等。

提前預埋

這個很容易了解,大家應該都記得,每次雙十一之前,淘寶總會提醒你下載下傳更新,按道理來講,活動還沒開始,更新啥呢?

做法是對于一部分靜态資料可以提前更新到你手機上,當你雙十一時就不用再遠端連接配接伺服器加載了,避免了消耗網絡資源。