架構(gòu)相關(guān):服務(wù)降級思路與方法
不點(diǎn)藍(lán)字關(guān)注,我們哪來故事?

正文如下
來源:www.cnblogs.com/
Courage129/p/14427020.html
什么是服務(wù)降級 服務(wù)等級定義 6個(gè)9含義 降級處理 兜底數(shù)據(jù) 限流降級 超時(shí)降級 故障降級 重試/自動處理 降級開關(guān) 爬蟲和機(jī)器人 讀降級 寫降級 前端降級 片段降級 提前預(yù)埋
什么是服務(wù)降級
如果看過我前面對服務(wù)限流的分析,理解服務(wù)降級就很容易了,對于一個(gè)景區(qū),平時(shí)隨便進(jìn)出,但是一到春節(jié)或者十一國慶這種情況客流量激增,那么景區(qū)會限制同時(shí)進(jìn)去的人數(shù),這叫限流,那么什么是服務(wù)降級呢?
簡單來說就是,將一些不太重要的景區(qū)項(xiàng)目砍掉,平時(shí)就那么三五八個(gè)人,景區(qū)可以開放湖中游泳啦,摸魚啦,捉蝦啦,有情況工作人員可以下湖撈你,但是現(xiàn)在客流量大了,工作人員關(guān)注不過來,都在湖里晃蕩萬一沉了不太安全,大手一揮,這個(gè)項(xiàng)目砍了,將工作人員分配在其他地方。
在互聯(lián)網(wǎng)中也有類似的降級措施,像之前雙11, 有段時(shí)間是只允許下單不允許退單或者改單,這樣做目的是什么呢?
還是為了保證服務(wù)的可用性,當(dāng)硬件軟件優(yōu)化到一定的程度還是有上限,這時(shí)候?qū)①Y源重點(diǎn)傾斜給核心業(yè)務(wù),那些不太重要的就砍掉,保證服務(wù)的可用性。
服務(wù)等級定義
服務(wù)等級定義 SLA(Service Level Agreement)是判定壓測是否異常的重要依據(jù)。壓測過程中,通過監(jiān)控核心服務(wù)狀態(tài)的 SLA 指標(biāo)數(shù)據(jù),可以更直觀地了解壓測業(yè)務(wù)的狀態(tài)。
SLA則是服務(wù)商與您達(dá)成的正常運(yùn)行時(shí)間保證。
關(guān)于這個(gè)的詳細(xì)解釋,可以參考阿里云的介紹:服務(wù)等級定義SLA(https://help.aliyun.com/document_detail/111729.html),這兒不過多描述,SLA 分為網(wǎng)絡(luò)服務(wù)和云服務(wù),提供商的在線保證率通常要求達(dá)到6個(gè)9。
6個(gè)9含義
6個(gè)9指99.9999%,也就是一個(gè)服務(wù)有99.9999%概率是安全的,6個(gè)9有多安全呢?
2個(gè)9 = (1-99%)X24 X 365 = 87.6 小時(shí) = 3.65天
3個(gè)9 = (1-99.9%)X24 X 365 = 8.76 小時(shí)
4個(gè)9 = (1-99.99%)X24 X 365 = 0.876 小時(shí) = 52.56分鐘
5個(gè)9 = (1-99.999%)X24 X 365 = 0.0876 小時(shí) = 5.256分鐘
6個(gè)9 = (1-99.9999%)X24 X 365 = 0.00876 小時(shí) = 0.5256分鐘 = 31秒
也就是,一年當(dāng)中,6個(gè)9的安全性最多會有31s服務(wù)是不可用,相對來說是極高的。
降級處理
兜底數(shù)據(jù)
這方面有很多例子,比如某些頁面掛了會返回尋親子網(wǎng)。可以對一些關(guān)鍵數(shù)據(jù)設(shè)置一些兜底數(shù)據(jù),例如設(shè)置默認(rèn)值、靜態(tài)值、設(shè)置緩存等。
默認(rèn)值 : 設(shè)置安全的默認(rèn)值,不會引起數(shù)據(jù)問題的值,比如庫存為0
靜態(tài)值 :請求的頁面或api無法返回?cái)?shù)據(jù),提供一套靜態(tài)數(shù)據(jù)展示,比如加載失敗提示重試,或者尋親子網(wǎng),或者跳到默認(rèn)菜單,給用戶一個(gè)稍微好一點(diǎn)的體驗(yàn)。
緩存 : 緩存無法更新便使用舊的緩存
限流降級
限流顧名思義,提前對各個(gè)類型的請求設(shè)置最高的QPS閾值,若高于設(shè)置的閾值則對該請求直接返回,不再調(diào)用后續(xù)資源,也就是當(dāng)流量洪峰到達(dá)的時(shí)候,可能需要丟棄一部分用戶來保證服務(wù)可用性,對于丟棄的用戶可以提供友好的提示,比如提示用戶當(dāng)前繁忙、稍后重試等。
限流需要結(jié)合壓測等,了解系統(tǒng)的最高水位,也是在實(shí)際開發(fā)中應(yīng)用最多的一種穩(wěn)定性保障手段。當(dāng)服務(wù)器壓力劇增的情況下,根據(jù)當(dāng)前業(yè)務(wù)情況及流量對一些服務(wù)和頁面有策略的降級,以此釋放服務(wù)器資源以保證核心任務(wù)的正常運(yùn)行。
超時(shí)降級
對調(diào)用的數(shù)據(jù)設(shè)置超時(shí)時(shí)間,當(dāng)調(diào)用失敗時(shí),對服務(wù)降級,舉個(gè)例子,當(dāng)訪問數(shù)據(jù)已經(jīng)超時(shí)了,且這個(gè)業(yè)務(wù)不是核心業(yè)務(wù),可以在超時(shí)之后進(jìn)行降級,比如商品詳情頁上有推薦內(nèi)容或者評價(jià),但是可以降級顯示評價(jià)暫時(shí)不顯示,這對主要的用戶功能——購物,不產(chǎn)生影響,如果是遠(yuǎn)程調(diào)用,則可以商量一個(gè)雙方都可以接受的最大響應(yīng)時(shí)間,超時(shí)則自動降級。
故障降級
如果遠(yuǎn)程調(diào)用的服務(wù)器掛了(網(wǎng)絡(luò)故障、DNS故障、HTTP服務(wù)返回錯(cuò)誤),則可以進(jìn)行降級, 例如返回默認(rèn)值或者兜底數(shù)據(jù)或者靜態(tài)頁面,也可以返回之前的緩存數(shù)據(jù)。
重試/自動處理
客戶端高可用:提供多個(gè)可調(diào)用的服務(wù)地址,這樣做
微服務(wù)重試:dubbo重試機(jī)制
API調(diào)用重試:當(dāng)達(dá)到重試次數(shù)后,增加訪問標(biāo)記,服務(wù)降級,異步探測服務(wù)是否恢復(fù)。
WEB端:在服務(wù)不可用時(shí),web端增加重試按鈕或自動重試可以提供更友好的體驗(yàn)。
自動重試需設(shè)置重試次數(shù)和數(shù)據(jù)冪等處理
降級開關(guān)
在服務(wù)器提供支持期間, 如果監(jiān)控到線上一些服務(wù)存在問題,這個(gè)時(shí)候需要暫時(shí)將這些服務(wù)去掉,有時(shí)候通過服務(wù)調(diào)用一些服務(wù),但是服務(wù)依賴的數(shù)據(jù)庫可能存在,網(wǎng)卡被打滿了,數(shù)據(jù)庫掛了,很多慢查詢等等,此時(shí)要做的就是暫停相關(guān)的系統(tǒng)服務(wù),也就是人工使用開關(guān)降級。開關(guān)可以放在某地,定期同步開關(guān)數(shù)據(jù),通過判斷開關(guān)值來決定是否做出降級。
開關(guān)降級還有一個(gè)作用,例如新的服務(wù)版本剛開發(fā)處在灰度測試階段,不太確定里面的邏輯等等是否正確,如果有問題應(yīng)該可以根據(jù)開關(guān)的值切回舊的版本。
在服務(wù)調(diào)用方設(shè)置一個(gè)flag,標(biāo)記服務(wù)是否可用,另外key可以存儲存儲在在本地,也可以存儲在第三方的配置文件中,例如數(shù)據(jù)庫、redis、zookeeper中。
爬蟲和機(jī)器人
分析機(jī)器人行為:短時(shí)間連續(xù)操作,agent,行為軌跡、拖拽(模擬登陸/秒殺/灌水)
爬蟲:引到到靜態(tài)頁或緩存頁
讀降級
簡而言之,在一個(gè)請求內(nèi),多級緩存架構(gòu)下,后端緩存或db不可用,可以使用前端緩存或兜底數(shù)據(jù)讓用戶體驗(yàn)好一點(diǎn)。
對于讀服務(wù)降級一般采用的策略有:暫時(shí)切換讀 : 降級到讀緩存、降級到走靜態(tài)化暫時(shí)屏蔽讀 : 屏蔽讀入口、屏蔽某個(gè)讀服務(wù)
通常讀的流程為: 接入層緩存→應(yīng)用層本地緩存→分布式緩存→RPC服務(wù)/DB
我們會在接入層、應(yīng)用層設(shè)置開關(guān),當(dāng)分布式緩存、RPC服務(wù)/DB有問題時(shí)自動降級為不調(diào)用。當(dāng)然這種情況適用于對讀一致性要求不高的場景。
頁面降級、頁面片段降級、頁面異步請求降級都是讀服務(wù)降級,目的是丟卒保帥,保護(hù)核心線程,或者因數(shù)據(jù)問題暫時(shí)屏蔽。
還有一種是頁面靜態(tài)化場景。動態(tài)化降級為靜態(tài)化 :比如,平時(shí)網(wǎng)站可以走動態(tài)化渲染商品詳情頁,但是,到了大促來臨之際可以將其切換為靜態(tài)化來減少對核心資源的占用,而且可以提升性能。其他還有如列表頁、首頁、頻道頁都可以這么處理。可以通過一個(gè)程序定期推送靜態(tài)頁到緩存或者生成到磁盤,出問題時(shí)直接切過去。靜態(tài)化降級為動態(tài)化 :比如,當(dāng)使用靜態(tài)化來實(shí)現(xiàn)商品詳情頁架構(gòu)時(shí),平時(shí)使用靜態(tài)化來提供服務(wù),但是,因?yàn)樘厥庠蜢o態(tài)化頁面有問題了,需要暫時(shí)切換回動態(tài)化來保證服務(wù)正確性。以上都保證了出問題時(shí)有預(yù)案,用戶可以繼續(xù)使用網(wǎng)站,不影響用戶購物體驗(yàn)。
寫降級
大家都知道硬盤性能比不上內(nèi)存性能,如果訪問量很高的話,數(shù)據(jù)庫頻繁讀寫可能撐不住,那么怎么辦呢,可以讓內(nèi)存(假如是Redis)庫來暫時(shí)滿足寫任務(wù),同時(shí)將執(zhí)行的指令記錄下來,然后將這個(gè)信息發(fā)送到數(shù)據(jù)庫,也就是不在追求內(nèi)存與數(shù)據(jù)庫數(shù)據(jù)的強(qiáng)一致性,只要數(shù)據(jù)庫數(shù)據(jù)與Redis數(shù)據(jù)庫中的信息滿足最終話一致性即可。
也就是說,正常情況下可以同步扣減庫存,在性能扛不住時(shí),降級為異步。另外,如果是秒殺場景可以直接降級為異步,從而保護(hù)系統(tǒng)。還有,如下單操作可以在大促時(shí)暫時(shí)降級,將下單數(shù)據(jù)寫入Redis,然后等峰值過去了再同步回DB,當(dāng)然也有更好的解決方案,但是更復(fù)雜,不是本篇的重點(diǎn)。
還有如用戶評價(jià),如果評價(jià)量太大,那么也可以把評價(jià)從同步寫降級為異步寫。當(dāng)然也可以對評價(jià)按鈕進(jìn)行按比例開放(比如,一些人看不到評價(jià)操作按鈕)。比如,評價(jià)成功后會發(fā)一些獎(jiǎng)勵(lì),在必要的時(shí)候降級同步到異步。
總結(jié)在cap原理和BASE理論中寫操作存在于數(shù)據(jù)一致性 這個(gè)環(huán)節(jié),降級的目的是為了提供高可用性,在多數(shù)的互聯(lián)網(wǎng)架構(gòu)中,可用性是大于數(shù)據(jù)一致性的。所以喪失寫入數(shù)據(jù)同步,通過上面的理論,我們也能勉強(qiáng)接受數(shù)據(jù)最終一致性。高并發(fā)場景下,寫入操作無法及時(shí)到達(dá)或抗壓,可以異步消費(fèi)數(shù)據(jù)/cache更新/log等方式
前端降級
當(dāng)系統(tǒng)出現(xiàn)問題的時(shí)候,盡量將請求隔離在離用戶最近的位置,避免無效鏈路訪問, 在后端服務(wù)部分或完全不可用的時(shí)候,可以使用本地緩存或兜底數(shù)據(jù),在一些特殊場景下,對數(shù)據(jù)一致性要求不高的時(shí)候,比如秒殺、抽獎(jiǎng)等可以做假數(shù)據(jù)。
JS降級
在js中埋降級開關(guān),在訪問不到達(dá),系統(tǒng)閾值的時(shí)候可以避免發(fā)送請求
主要控制頁面功能的降級,在頁面中,通過JS腳本部署功能降級開關(guān),在適當(dāng)時(shí)機(jī)開啟/關(guān)閉開關(guān)。
接入層降級
可以在接入層,在用戶請求還沒到達(dá)服務(wù)的時(shí)候,通過、Nginx + Lua、Haproxy + lua過濾無效請求達(dá)到服務(wù)降級的目的, 主要控制請求入口的降級,請求進(jìn)入后,會首先進(jìn)入接入層,在接入層可以配置功能降級開關(guān),可以根據(jù)實(shí)際情況進(jìn)行自動/人工降級。這個(gè)可以參考第17章,尤其在后端應(yīng)用服務(wù)出問題時(shí),通過接入層降級從而給應(yīng)用服務(wù)有足夠的時(shí)間恢復(fù)服務(wù)。
應(yīng)用層降級
主要控制業(yè)務(wù)的降級,在應(yīng)用中配置相應(yīng)的功能開關(guān),根據(jù)實(shí)際業(yè)務(wù)情況進(jìn)行自動/人工降級。
SpringCloud中可以通過Hystrix配置中心可以進(jìn)行人工降級,也可以根據(jù)服務(wù)的超時(shí)時(shí)間進(jìn)行自動降級, Hystrix是Netflix開源的一款針對分布式系統(tǒng)的延遲和容錯(cuò)庫,目的是用來隔離分布式服務(wù)故障。它提供線程和信號量隔離,以減少不同服務(wù)之間資源競爭帶來的相互影響;官網(wǎng)講Hystrix提供優(yōu)雅降級機(jī)制;提供熔斷機(jī)制使得服務(wù)可以快速失敗,而不是一直阻塞等待服務(wù)響應(yīng),并能從中快速恢復(fù)。Hystrix通過這些機(jī)制來阻止級聯(lián)失敗并保證系統(tǒng)彈性、可用。下圖是一個(gè)典型的分布式服務(wù)實(shí)現(xiàn)。

片段降級
例如打開淘寶首頁,這一瞬間需要加載很多數(shù)據(jù),有靜態(tài)的例如圖片、CSS、JS等,也有很多其他商品等等,這么多數(shù)據(jù)中,如果一部分沒有請求到,那么就可以片段降級,意思是就不加載這些數(shù)據(jù)了,用其他數(shù)據(jù)頂替,例如其他商品信息或者等等。
提前預(yù)埋
這個(gè)很容易理解,大家應(yīng)該都記得,每次雙十一之前,淘寶總會提醒你下載更新,按道理來講,活動還沒開始,更新啥呢?
做法是對于一部分靜態(tài)數(shù)據(jù)可以提前更新到你手機(jī)上,當(dāng)你雙十一時(shí)就不用再遠(yuǎn)程連接服務(wù)器加載了,避免了消耗網(wǎng)絡(luò)資源。
往期推薦
-END-
↑ 點(diǎn)擊上方關(guān)注我公號?↑?
我是 泥瓦匠,堅(jiān)持分享編程,算法,Java 等干貨教程
一枚醫(yī)科大本科生,開源小作者,半吊子創(chuàng)業(yè)愛好者...
半吊子的自己在試錯(cuò),不知道以后會干什么,但享受現(xiàn)在的試錯(cuò),試錯(cuò)給我驚訝的生活
喜歡公號的互動分享,感謝關(guān)注,路上遇見了你,同一小段時(shí)間之路,相伴 ~
長按識別,加我微信

