這套SLO運(yùn)營體系與報警,不允許還有SRE沒看過!
SLO是SRE中提出的一個工程理論,指出SLO指定了服務(wù)可靠性的目標(biāo)水平,是做出數(shù)據(jù)決策的一個關(guān)鍵指標(biāo),也是SRE的核心。
結(jié)合SRE中的可靠性工程,B站也落地了自己的一整套實踐體系,如下圖所示,最上方是我們跟研發(fā)的協(xié)作體系,研發(fā)可以看到SRE的幾種角色,比如Oncall輪值、核心業(yè)務(wù)BP、PaaS平臺專家以及專門負(fù)責(zé)可靠性工程開發(fā)的SRE。可靠性工程中對服務(wù)的質(zhì)量運(yùn)營就是通過SLO工程驅(qū)動的可觀測、變更管理和報警治理。
一、可用性指標(biāo)困局
1.可用性對象多,指代不清
可用性的指向?qū)ο蠛芏?,因此我們可能不清楚可用性的具體內(nèi)容。實際上,可用性的度量可以是生產(chǎn)運(yùn)行的一個服務(wù)或應(yīng)用、應(yīng)用下的某一個接口、某一個業(yè)務(wù)模塊、某個團(tuán)隊或部門。
2.可用性度量難,數(shù)據(jù)標(biāo)準(zhǔn)、建模難
- 不可用難定義
度量可用性其實很難,首先我們要解決“什么是不可用”的問題。怎樣的請求屬于失敗,需要提前制定標(biāo)準(zhǔn),比如一個請求失敗是不可用,或一分鐘內(nèi)錯誤率超過某個閾值是不可用,由此才能推動后續(xù)實踐。
- 事故報告召回低、統(tǒng)計數(shù)據(jù)維度單一、監(jiān)控指標(biāo)難統(tǒng)計
傳統(tǒng)的可用性度量大多是基于故障的度量,如mttr指標(biāo)。但可用性的事故報告召回低,只有出現(xiàn)嚴(yán)重事故,才會生成故障報告。對于服務(wù)的某些短時間抖動,我們一般不會通過數(shù)據(jù)報告的方式復(fù)盤。
3.運(yùn)營需求場景多 ,報警、損失、報表等
可用性的數(shù)據(jù)還應(yīng)用于運(yùn)營的場景。常見的運(yùn)營需求包括報警能不能基于可用性完成;若出現(xiàn)生產(chǎn)故障,可用性損失的數(shù)據(jù)能否自動產(chǎn)出,是否需要產(chǎn)出年度、月度或季度的可用性報表。
4.指標(biāo)、報警多,重點不清
隨著微服務(wù)體系發(fā)展,指標(biāo)和報警的數(shù)量攀升。當(dāng)SRE針對具體問題進(jìn)行故障排查時,由于指標(biāo)過于豐富,我們?nèi)菀撞磺宄挪橹攸c或排查順序。除此之外,每次出現(xiàn)事故都會加報警,導(dǎo)致難以區(qū)分報警工單和巡檢,最終從報警的通道推送出來的基本都是噪音。
5.報警治理難,多維度報警無從下手
報警存在分層,IAAS、中間件、應(yīng)用、業(yè)務(wù)、終端等層面都有指標(biāo),因此通知數(shù)量高達(dá)幾萬條。為了保證通知到位,各項通知逐漸趨于高速度、高頻率,通知內(nèi)卷化嚴(yán)重。
二、SLI指標(biāo)的選擇和SLO的度量
1.SLO的方法論
先看一下整個SLO的方法論,這個方法論比較簡單。
- SLI(服務(wù)等級指標(biāo)):量化指標(biāo),如服務(wù)的可用性延遲或容量。
- SLO(服務(wù)等級目標(biāo)):量化指標(biāo)的目標(biāo)。
- SLA(服務(wù)等級協(xié)議):SLO與后果,比如低于這個目標(biāo)之后,需承擔(dān)的后果和賠償。例如,公有云的云服務(wù)都制定了SLA協(xié)議,若可用性低于某個值,則需要以代金券等方式進(jìn)行賠償。在SLO工程中,基本上不會涉及SLA。
SLO指定了服務(wù)可靠性的目標(biāo)水平,是做出可靠性決策的關(guān)鍵數(shù)據(jù),也是SRE實踐的核心。
2.常見SLO模型
對于一些常見的SLO模型,SRE也給了一個例子,是一個名為VALET的模型,對應(yīng)了5條指標(biāo),即容量、可能性、延遲、錯誤和工單。
3.實施SLO的理想流程
在SRE中,一個實施SLO的理想流程如下:
1)SLI選擇計算
首先,選擇指標(biāo)。以可用性為例,若指標(biāo)屬于請求驅(qū)動型,那么成功響應(yīng)的請求比例除以總的請求,即可得到可用性量化指標(biāo)。此外,該指標(biāo)還能夠度量服務(wù)請求的延遲與請求的質(zhì)量。
其次,定義錯誤。比如,HTTP 500、504、503是錯誤,或404、429、403是錯誤?
最后,度量數(shù)據(jù)。通過應(yīng)用的服務(wù)器日志、負(fù)載均衡或客戶端進(jìn)行度量時,SRE里推薦選擇負(fù)載均衡度量,因為這一層的度量成本與客戶端相較更低,并且可以度量從負(fù)載均衡到服務(wù)內(nèi)部所有鏈路的數(shù)據(jù)。
2)SLO定義
數(shù)據(jù)度量完成后,即可進(jìn)行SLO的定義,其具體做法與SLI類似。
3)錯誤預(yù)算
即基于你的SLI指標(biāo),得出時間窗口內(nèi)的允許錯誤預(yù)算。例如,可用性全年是99.99%,那么基于一年的時間窗口就可得知一年內(nèi)99.99%的SLO允許的不可用時間是52分鐘。
當(dāng)錯誤預(yù)算消耗殆盡時,可以制定一個策略,比如要求研發(fā)凍結(jié)生產(chǎn)系統(tǒng)的日常迭代,除非研發(fā)要做緊急的bug修復(fù),或需要優(yōu)化生產(chǎn)的穩(wěn)定性。
4)儀表盤和報表
最后,需要一個儀表盤和報表來完成數(shù)據(jù)的展示和可視化,并持續(xù)改進(jìn)SLO。
4.SLO第一次嘗試
我們在2019年做了第一次嘗試,按照這套體系去做整個SLO體系的度量和元信息的關(guān)聯(lián)。當(dāng)時的目標(biāo)是做一個非常準(zhǔn)確的度量數(shù)據(jù),這個數(shù)據(jù)需要體現(xiàn)線上服務(wù)真實的可用性指標(biāo),比如能體現(xiàn)它全年的可用性是多少,同時也能及時發(fā)現(xiàn)線上的問題。但在實踐了大半年或一年左右之后,這套邏輯就難以為繼。
5.失敗反思
1)SLO生命周期運(yùn)營
反思以上問題后,我們重新構(gòu)建整個SLO生命周期的體系邏輯。
- 度量SLI,設(shè)置SLO
做指標(biāo)度量,設(shè)置SLO,增加指標(biāo)治理的步驟,提升指標(biāo)的準(zhǔn)確率。指標(biāo)治理完成后,度量可用率、數(shù)據(jù)延遲和業(yè)務(wù)指標(biāo),使SRE和研發(fā)具備一致的觀測能力。
- SLO報警及智能診斷
基于這些指標(biāo)做SLO的告警,將其與傳統(tǒng)的告警區(qū)分,務(wù)必提供一個精確高效、透明分發(fā)的渠道。
- 錯誤預(yù)算與SLO報警運(yùn)營
保留錯誤預(yù)算,但將其與SLO報警相結(jié)合,用于找出服務(wù)故障的共性因素,并與研發(fā)共同進(jìn)行穩(wěn)定性的治理。
- SLO報表與儀表盤
做報表和儀表盤,使業(yè)務(wù)能綜合觀察到日、周、月、季、年的歷史可用率報表,能看到錯誤預(yù)算消耗,包括可用率的排名等內(nèi)容。
- SLO生態(tài)建設(shè)
建立整個SLO的生態(tài)數(shù)據(jù),一定要把SLO的指標(biāo)擴(kuò)展到上層的使用平臺,比如CI、CD、壓測平臺或內(nèi)部的多活管控平臺。只要是服務(wù)變更的核心平臺,就可以把服務(wù)SLO的指標(biāo)擴(kuò)展到平臺上,使研發(fā)在平臺中就能看到服務(wù)實時的可用性指標(biāo),也可以用這個指標(biāo)完成變更預(yù)檢、發(fā)布觀測、智能阻斷等。
整個模式建立在CMDB元信息、微服務(wù)框架、可觀測能力、報警中心、事件中心以及AIOps能力的基礎(chǔ)上。
2)可用性指標(biāo)選擇
進(jìn)行指標(biāo)可用性的度量最常見的兩種模式:一是度量請求成功率,二是度量服務(wù)的可用時間。
請求成功率:只要定義什么是錯誤,就能知道錯誤率,從而就能得出請求成功率。它的計算非常簡單,你只要找出錯誤的code,再做治理,最后統(tǒng)計出錯誤code即可。
可用時間:這個計算會更為復(fù)雜,首先要度量什么是不可用時間。比如,一分鐘服務(wù)的錯誤率大于20%時,就認(rèn)定這一分鐘不可用,那么統(tǒng)計出不可用的時間,算出總時間,即可得到服務(wù)的可用性。
根據(jù)我們之前的實踐經(jīng)驗,對以上兩種方式的選擇主要考慮指標(biāo)的準(zhǔn)確度。哪個指標(biāo)有價值,哪個指標(biāo)能發(fā)現(xiàn)線上問題,哪個指標(biāo)對業(yè)務(wù)價值大,就用哪個指標(biāo)。而對報警的精確度來說,基于時間的統(tǒng)計方式的錯誤率是固定的,錯誤率不達(dá)標(biāo)也不代表用戶不受影響,所以通常會選擇基于請求成功率。線上問題發(fā)現(xiàn)率的統(tǒng)計也是基于請求成功率,這對業(yè)務(wù)價值最大。
3)SLI指標(biāo)治理:錯誤治理
運(yùn)用請求成功率最核心的一點就是要完成錯誤的標(biāo)準(zhǔn)化和錯誤的識別。
在一個網(wǎng)絡(luò)鏈路中,會出現(xiàn)很多錯誤。比如,基于TCP/HTTP的一個簡單模型來看,Client發(fā)SYN包的時候,Server有可能遇到網(wǎng)絡(luò)不可查或者網(wǎng)絡(luò)超時等情況,然后Client會發(fā)送SYN Retry。當(dāng)把數(shù)據(jù)包發(fā)過去之后,對端的端口可能掛了,數(shù)據(jù)包也會Reset。
例如,在讀緩存或者讀DB這些強(qiáng)依賴或者依賴一個下游服務(wù)不可用時,服務(wù)會出現(xiàn)請求正確性的錯誤,雖然在一定的時間內(nèi)將請求處理完畢,但相應(yīng)的數(shù)據(jù)出現(xiàn)錯誤。
因此在這條鏈路中,基于Client和Server的視角都可能出現(xiàn)不同類別的錯誤。不管是基于SLB的Client的視角,還是基于服務(wù)上下游調(diào)用的Client的視角,對下游服務(wù)的熔斷、下游服務(wù)網(wǎng)絡(luò)不可達(dá)、下游服務(wù)應(yīng)用無響應(yīng)或者響應(yīng)超時,以及下游服務(wù)雖響應(yīng)但返回了一個錯誤的內(nèi)容等這些情況,都是不可用的場景。
而基于Server的視角,只有這種場景能通過Server的視角度量出來:Server返回請求,但請求返回的是錯誤內(nèi)容,如業(yè)務(wù)錯誤code碼。
- 錯誤碼標(biāo)準(zhǔn)化
SLB視角:HTTP 5xx
當(dāng)錯誤的類型定義清楚后,就要定義我們的Code碼,而從負(fù)載均衡的視角來看,比如說我們的基本是5xx。
Server視角:業(yè)務(wù)Code -5xx
我們參考HTTP 5xx對業(yè)務(wù)的Code碼做了一個-5xx的定義,比如服務(wù)內(nèi)部錯誤,導(dǎo)致內(nèi)部業(yè)務(wù)邏輯無法處理,會把錯誤return出來,一般會出現(xiàn)一個-500或-504。
如果因為調(diào)用下游服務(wù)超時而導(dǎo)致整個鏈路的耗時消耗完畢,服務(wù)無法處理,會拋一個-504;如果服務(wù)接了限流的框架,限流時會拋一個-509。
Client視角:業(yè)務(wù)Code -5xx
4)可用性SLI:多維計算
最終對服務(wù)的度量集中在兩個維度:
- SLB HTTP 5xx:
從SLB的層面看負(fù)載均衡中所上報的服務(wù)的5xx錯誤量、服務(wù)的QPS以及服務(wù)的耗時。SLB層面若產(chǎn)生了5xx的Code碼,那就代表應(yīng)用訪問超時、容器OOM或者進(jìn)程Panic等不可用,這都是一些非常嚴(yán)重的故障。
- HTTP/gRPC Server -5xx:
另一層面是在服務(wù)本身的Metrics層面上報。我們的服務(wù)可能分為HTTP的協(xié)議和gRPC的協(xié)議,不同的協(xié)議可能是不同的Metrics,所以最終會在SLB層面去度量SLO,然后在服務(wù)層面度量HTTP和gRPC的請求。
我們在度量服務(wù)本身的Metrics時,發(fā)現(xiàn)它出現(xiàn)了一些-5xx的Code碼,這個對應(yīng)的場景就是應(yīng)用HTTP Code 200,但因依賴下游服務(wù)、讀取DB、CACHE失敗等系統(tǒng)錯誤時,則會在應(yīng)用Metrics側(cè)上報業(yè)務(wù)Code的錯誤指標(biāo)。
通過這兩種指標(biāo)的度量,就能度量出服務(wù)所有的故障場景。
5)數(shù)據(jù)延遲SLI
除了可用性的度量外,我們還對服務(wù)的延遲指標(biāo)做了度量,此延遲所指的不是接口的延遲,而是存儲和數(shù)據(jù)層面的延遲。因為我們做了同城雙活,同城雙活中有很多數(shù)據(jù)同步的場景,比如數(shù)據(jù)庫的同步和緩存的同步等。數(shù)據(jù)若產(chǎn)生延遲,將嚴(yán)重影響用戶體驗。
6)業(yè)務(wù)指標(biāo)SLI
技術(shù)指標(biāo)有時無法發(fā)現(xiàn)業(yè)務(wù)指標(biāo)層面的問題和故障。
我們以前遇到過一些案例:如用戶頻繁掉登錄,最后發(fā)現(xiàn)是APP上誤踢登錄;還有用戶充值失敗,最后發(fā)現(xiàn)是業(yè)務(wù)邏輯的bug。
7)多對象、多SLI、多指標(biāo)計算
最終我們的度量方式是多對象,多SLI指標(biāo),多SLI實現(xiàn)。
度量對象的第一層級就是業(yè)務(wù),業(yè)務(wù)通過大數(shù)據(jù)的一些流式實時計算以及數(shù)據(jù)庫的Binlog來做度量,它用于度量在線人數(shù)、播放量、評論、彈幕、登錄和營收等指標(biāo)。
我們還度量了業(yè)務(wù)的某些核心功能。例如,無論是發(fā)彈幕評論還是登錄,都有對應(yīng)的服務(wù)端的API,它面向用戶側(cè)的公網(wǎng)訪問。我們會把這些API度量出來,然后通過服務(wù)端的技術(shù)指標(biāo)來觀察這些功能的可能性。因為業(yè)務(wù)指標(biāo)的度量更多是一個吞吐量的變化,通過服務(wù)端的技術(shù)指標(biāo)對這些接口做度量,觀察公網(wǎng)接口,最終將成功或失敗的結(jié)果反饋給用戶,由此能度量出核心功能的可用性。
生產(chǎn)系統(tǒng)中有成千上萬的API,不可能度量出所有的API,所以我們有一個兜底策略,即對所有的應(yīng)用都使用這套可用性的度量指標(biāo)。針對接口,我們可能會在SLB、API GW這種偏外網(wǎng)的入口層面做接口的度量,應(yīng)用方面則會在Promethues埋點,同時也會度量它用到的存儲組件的延遲指標(biāo)。在實踐中,我們發(fā)現(xiàn)技術(shù)指標(biāo)召回的問題遠(yuǎn)遠(yuǎn)大于業(yè)務(wù)指標(biāo)召回的問題,因為業(yè)務(wù)指標(biāo)一旦產(chǎn)生問題,就代表生產(chǎn)已經(jīng)發(fā)生了非常明顯的故障。
由于不是每一個服務(wù)都直接對用戶提供公網(wǎng)功能,很多服務(wù)可能時內(nèi)網(wǎng)服務(wù),或是下游依賴的服務(wù),產(chǎn)生不可用問題的時候就會被SLO發(fā)現(xiàn),同時發(fā)出告警。但最終用戶可能沒有感知,因為上游鏈路很長,很有可能在某一個鏈路就被熔斷或者被降級,所以服務(wù)的故障不代表最終用戶的故障,服務(wù)維度的技術(shù)指標(biāo)所召回的問題遠(yuǎn)遠(yuǎn)大于業(yè)務(wù)指標(biāo)召回的問題。
三、SLO報警實踐
前文也提到了告警的問題,例如,每次出事故都加告警、報警狼來了、全是噪音以及報警準(zhǔn)確率低等,令人無從下手……問題在哪?我們在做SLO告警時慢慢發(fā)現(xiàn)了根因。
1.SLO的告警是果,其他告警是因
做故障復(fù)盤時之所以要加告警,是因為發(fā)現(xiàn)這個服務(wù)的CPU產(chǎn)生抖動、服務(wù)磁盤的使用率過高、磁盤滿了都會導(dǎo)致服務(wù)出異常。每一個因最終都有可能影響服務(wù)的穩(wěn)定性,但是SLO是真正代表服務(wù)的可用性的指標(biāo),它是一個果,只要你有了這個果,就能做到兜底,無需再加各種因。
我們以往的報警沒有區(qū)分系統(tǒng)錯誤和業(yè)務(wù)錯誤,也沒有清晰定義出研發(fā)需要關(guān)注的錯誤,導(dǎo)致每天可能有幾萬條報警,研發(fā)難以一一查看。如果Code碼不是200就報警,那么這種報警就沒有任何意義。
最終我們以SLO告警作為核心,規(guī)劃新的報警治理。
1)SLO告警降噪思路
- 研發(fā)只關(guān)注應(yīng)用告警
研發(fā)只需要關(guān)注應(yīng)用告警,包括SLO的告警和影響SLO的常見因素,最常見的三種是依賴錯誤、中間件異常、容量。我們可以通過HPA的策略解決容量問題,比如全部覆蓋HPA,在CPU超過50%或者60%的擴(kuò)容情況下,就不會每天收到大量報警。
- 通過應(yīng)用SLO指標(biāo)發(fā)現(xiàn)對下層(中間件、組件)依賴錯誤
以數(shù)據(jù)庫不可用為例,以往研發(fā)可能會收到業(yè)務(wù)的數(shù)據(jù)庫不可用的告警,或者緩存。如果產(chǎn)生了主從切換,或緩存的某一個節(jié)點宕機(jī),研發(fā)可能會收到業(yè)務(wù)用到某一個緩存不可用而宕機(jī)的告警,但是現(xiàn)在的思路則是,研發(fā)無需再關(guān)注中間件層面的告警,只需通過自己應(yīng)用側(cè)埋點的指標(biāo)就可以發(fā)現(xiàn)中間件的問題。
- 下層告警對研發(fā)透明
服務(wù)可以上報對緩存的一個依賴指標(biāo),它會上報出對緩存的每一次請求是否成功,耗時多少等情況。如果緩存出現(xiàn)問題,按業(yè)務(wù)指標(biāo)直接上報出來即可。如果緩存發(fā)生了主從切換,但是最終對服務(wù)的SLO沒有任何影響,那么研發(fā)完全可以無視這個事件。同時,難免有些業(yè)務(wù)未能達(dá)成此類最佳實踐,研發(fā)也可以按需去訂閱下層的告警。
2)SLO告警運(yùn)營體系:1-5-10
- 設(shè)置SLO告警
在設(shè)置SLO告警時,需要精確的計算邏輯避免無效告警。這方面我們使用了SRE中提到的錯誤預(yù)算窗口、消耗率、多消耗率報警及多窗口的計算策略。
- 分發(fā)和協(xié)同
傳統(tǒng)的分發(fā)和協(xié)同一般通過短信或者IM工具,比如釘釘、企業(yè)微信等渠道。并且傳統(tǒng)的報警都是面向于某一個應(yīng)用,發(fā)送給權(quán)限人,但由于元信息平臺人員的權(quán)限一般不會因為組織架構(gòu)調(diào)整或者是研發(fā)的職責(zé)調(diào)整而出現(xiàn)變更,所以難以精確識別出關(guān)注應(yīng)用告警的研發(fā)人員。比如,一個服務(wù)產(chǎn)生問題,可能收到報警的有三四十人,其中真正關(guān)心服務(wù)的人員可能只有兩三個。
- 根因定位
我們做了一個智能診斷的平臺,結(jié)合可觀測,使研發(fā)能夠在5分鐘內(nèi)定位問題。
- 運(yùn)營分析
導(dǎo)出SLO告警的數(shù)據(jù),分析每個團(tuán)隊的處理效率。結(jié)合研發(fā)反饋的告警有效性,將這些數(shù)據(jù)用于運(yùn)營分析,以此了解告警的預(yù)算消耗、告警觸發(fā)的原因。告警準(zhǔn)確率高、低噪音、故障高召回、智能快速診斷、公開透明、高效協(xié)同是這一套機(jī)制運(yùn)轉(zhuǎn)下去的前提。
SRE提出了兩個概念,第一個概念是錯誤預(yù)算,第二個是消耗率。
錯誤預(yù)算對風(fēng)險識別、故障定級和穩(wěn)定性決策十分重要。如果要做變更,比如生產(chǎn)要做網(wǎng)絡(luò)割接、或某個服務(wù)要變更維護(hù),一定會對服務(wù)產(chǎn)生影響。過去對服務(wù)的嚴(yán)重程度是以時間來度量,現(xiàn)在轉(zhuǎn)而查看它會消耗多少的錯誤預(yù)算。
3)SLO告警策略
- 目標(biāo)錯誤率≥SLO
基于你制定的SLO(包括錯誤預(yù)算和消耗率)制定報警策略,若目標(biāo)錯誤率大于SLO,就可以告警。
缺點:假如這個服務(wù)每時每刻的錯誤率剛好都是0.1%,若一分鐘報警一次,一天能報1440次,但這個服務(wù)的可用率剛好還是99.9%,滿足SLO的要求。
- 錯誤預(yù)算窗口
增加時間窗口。例如,報警策略是消耗30天的窗口的5%,即36小時,把36小時的錯誤預(yù)算消耗完畢后,再發(fā)出一條告警。這種告警也不太合適,原因有二,其一,假設(shè)以一個36小時的窗口來做計算,那么報警觸發(fā)后,在36小時的滑動窗口的一段時間內(nèi),會持續(xù)發(fā)出告警;其二,假如錯誤率剛好是0.1%,剛好是SLO閾值的臨界點,那么就要達(dá)到36小時才能觸發(fā)告警。
- 增加報警持續(xù)時間
可以增加單個報警的持續(xù)時間,比如SLO低于閾值10分鐘之后發(fā)出告警,或者低于SLO閾值一小時后發(fā)出告警。
缺點:不論服務(wù)是100%不可用,還是0.1%不可用,都是在10分鐘后發(fā)出告警,報警的靈敏度與服務(wù)的錯誤率無關(guān)。針對此問題,SRE提出了消耗率的概念。
- 多次消耗率報警
嚴(yán)重故障:1小時消耗月度2%(14.4h)的預(yù)算消耗,發(fā)出緊急報警。
輕微故障:6小時消耗月度5%(36h)的錯誤預(yù)算,發(fā)出緊急報警。
兜底策略:3天消耗月度10%(3d)的預(yù)算,發(fā)出故障工單。
- 多窗口,多消耗率報警
以一小時的窗口做報警計算為例,若5分鐘時錯誤已經(jīng)告警,那么接下來的55分鐘也會繼續(xù)發(fā)出告警。因此這個策略增加另一個窗口,在報警和恢復(fù)時檢查是否仍然達(dá)到錯誤預(yù)算消耗速率。
這需要兩個條件,一是必須把一個小時的錯誤預(yù)算消耗完畢,二是在接下來檢測的時間窗口內(nèi)錯誤率仍很高,應(yīng)對的場景是服務(wù)的可用率馬上歸零,又馬上恢復(fù)。這種場景下報警可立即觸發(fā),并立即恢復(fù)。
由于錯誤預(yù)算和消耗率理解起來太復(fù)雜,所以用時間窗口、可用率和錯誤量的概念替代錯誤預(yù)算和消耗率。我們將服務(wù)進(jìn)行線上分級,按照服務(wù)的等級分梯度設(shè)置報警條件,緊急窗口用于發(fā)現(xiàn)嚴(yán)重事故,非緊急的窗口用于處理一些低速流血的問題。
比如,緊急窗口用于發(fā)現(xiàn)服務(wù)的平均可用率低于某個值,同時錯誤量最近一分鐘大于某個值,這就是緊急的報警窗口。非緊急窗口是指服務(wù)一天的可用性剛好低于SLO,制定好報警策略后,此時報警能夠發(fā)現(xiàn)線上的緊急問題和非緊急問題。
4)SLO告警分發(fā)、協(xié)同
我們借助事件中心的分發(fā)能力,重新做了一套告警分發(fā)協(xié)同的機(jī)制。
這種方式可以實現(xiàn)對人員的精確識別,并擁有一個高質(zhì)量的協(xié)同群渠道。整個報警采取公開、透明、協(xié)同的處理方式,補(bǔ)充了傳統(tǒng)報警方式缺失的能力。但需要注意,不能用一些誤報率很高的報警運(yùn)行這套機(jī)制,這種低質(zhì)量的告警推送到群內(nèi)會產(chǎn)生刷屏現(xiàn)象。
5)SLO告警根因定位
步驟如下:
在我們的場景中,只垂直做服務(wù)的故障,就會發(fā)現(xiàn)根因定位邊界很清晰?;跇I(yè)務(wù)指標(biāo)、應(yīng)用指標(biāo)、中間件指標(biāo)以及服務(wù)的容量指標(biāo),就可以發(fā)現(xiàn)服務(wù)的故障點。因此,我們只需要做故障定界,無需立刻定位服務(wù)的根因。在當(dāng)前的微服務(wù)架構(gòu)下,只要知道服務(wù)故障點的位置,就可立刻止損。
6)案例分享
我們在群里推出了一條SLO的告警,并在告警卡片里會推送一個SLO的診斷鏈接,然后直接@服務(wù)所負(fù)責(zé)的或做過變更的研發(fā)。研發(fā)直接點開鏈接就可以快速地做故障的定界,確認(rèn)接口和服務(wù)的錯誤類型。
在根因分析方面,我們會觀察它依賴的資源、依賴的下游服務(wù)或者依賴的中間件,使研發(fā)能快速得知具體的服務(wù)故障點。故障定界后,研發(fā)做止損,最后服務(wù)恢復(fù),完成故障修復(fù)。針對SLO的故障場景,上文提到用于生產(chǎn)的實際模型,可以達(dá)成1分鐘報警、研發(fā)5分鐘完成故障定界兩個目標(biāo)。
四、SLO運(yùn)營
1.SLO指標(biāo)運(yùn)營
2.SLO報警運(yùn)營
只要把告警發(fā)到群里,研發(fā)都會處理,因為告警非常準(zhǔn)確,一旦發(fā)生就代表服務(wù)出問題。與研發(fā)唯一的分歧是SLO告警出來后表示服務(wù)不可用,但是這個服務(wù)沒那么重要,研發(fā)會基于上游容忍自己服務(wù)錯誤的原因,將其判斷為誤報。
這種場景下報警仍然準(zhǔn)確,但需要抑制服務(wù)的一些報警條件或者觸發(fā)條件,降低敏感度。
3.SLO與變更檢測
要建設(shè)整個SLO的生態(tài),就要把SLO與變更檢測相結(jié)合。我們把實時的SLO指標(biāo)如可用率、錯誤、QPS、延遲SLO擴(kuò)展到容器平臺之類的上層平臺,服務(wù)在發(fā)布和變更時集成了SLO的指標(biāo)大盤,研發(fā)可以實時看到自己服務(wù)的可用率和錯誤量。在多活的管控平臺中,多活切量時也有服務(wù)SLO指標(biāo)的觀測,我們可以用這些指標(biāo)做變更的預(yù)檢,觀察服務(wù)整體的健康情況。
在發(fā)布中也可以做觀測和智能阻斷,一旦發(fā)現(xiàn)服務(wù)的指標(biāo)出現(xiàn)了可用性的下跌,可以智能阻斷該次變更。
Q&A
Q1: BiliBili是度量了每個服務(wù)的SLO嗎?
A1:對,我們度量的對象有三種,第一是業(yè)務(wù),第二是通過API來度量業(yè)務(wù)的某一個功能,第三是使用這套指標(biāo)針對每個服務(wù)做一個度量。因為生產(chǎn)的API非常多,不可能把所有API都度量出來。面對服務(wù)沒有任何指標(biāo)的情況,就無法進(jìn)行度量,但只要有指標(biāo)就可以度量出來。
Q2: 如果想度量一個系統(tǒng)的可用率,這個系統(tǒng)由50個微服務(wù)組成,是取平均值嗎?
A2:不是的,取平均值并無意義。首先要看是中間件還是一個業(yè)務(wù)系統(tǒng)。假設(shè)是一個業(yè)務(wù)系統(tǒng),比如登錄系統(tǒng),里面可能有10個微服務(wù),可以把登錄相關(guān)的核心接口定義出來,用它們的可用率度量這個登錄系統(tǒng)的可用率,把所有的錯誤量、請求量全部相加,累加之后再去算整體的可用率,而不應(yīng)該取平均值。因為如果服務(wù)某一個功能的可用率很低,平均之后這個數(shù)據(jù)就會失真。
比如有一個服務(wù)每天的請求量是1萬,今天的可用率只有90%,另一個服務(wù)每天的請求量可能只有100,這兩個數(shù)據(jù)一旦平均,數(shù)據(jù)失真就會特別嚴(yán)重,所以不建議取平均值。
Q3: oncall人員會收到所有的告警嗎,若收不到,有問題無法觸發(fā)oncall人員,如果收又會被告警轟炸,這種情況怎么辦?
A3:首先告警體系本身是分級的,處在不同層級的人關(guān)注的告警不一樣。例如存儲中間件的同學(xué)會關(guān)注中間件的指標(biāo),SRE可能會關(guān)注應(yīng)用的指標(biāo),也會關(guān)注部分中間件的指標(biāo),而研發(fā)關(guān)注的也是應(yīng)用本身的指標(biāo)和部分中間件的指標(biāo),相關(guān)人員需要接收自己有權(quán)限的服務(wù)報警。
至于告警轟炸問題,傳統(tǒng)的告警加的是因。只要這個指標(biāo)的波動有可能影響服務(wù)的可用性,我們就會添加一堆告警,這種情況下屬于告警轟炸。但如果能把服務(wù)的SLO指標(biāo)清晰定義并度量出來,用這個指標(biāo)做報警,由此很多基于因的報警都可以慢慢下線。
Q4:這套體系是否只針對業(yè)務(wù)開發(fā),對SRE 有沒有告警降噪的案例?
A4:不是的,這套體系針對業(yè)務(wù)開發(fā)和SRE,雙方共同關(guān)注告警。至于告警降噪的案例,我們這套告警上線后,對應(yīng)用的其他告警做了策略的調(diào)整,包括告警的下線。比方說有一個APP接了限流框架,觸發(fā)限流的告警,每天的告警數(shù)量可能有幾萬條。SLO告警上線后,我直接取消了這個告警。因為服務(wù)觸發(fā)限流之后,只要達(dá)到一定的錯誤率,就會被SLO報警所觸發(fā),然后按照企微協(xié)同,再到SLO的根因定位的一套機(jī)制處理限流告警,所以無需一些基于因的度量告警。
Q5:線上壓測流量、測試用戶的誤告怎么處理?
A5:測試用戶可以通過生產(chǎn)一種灰度或者染色的方式來處理,即對用戶流量做一些打標(biāo)。我們可以在指標(biāo)上報的時候加上這種標(biāo)簽,這個操作在我們的系統(tǒng)種稱為染色,這個請求帶有一個顏色標(biāo)簽,那么在它的指標(biāo)中,染色的標(biāo)簽可以識別并被上報。
我們在測試環(huán)境做SLO指標(biāo)度量和報警的時候,就不會再看染色的流量,而是只看基準(zhǔn)版本的流量。如果生產(chǎn)的問題很嚴(yán)重,可以用類似的方式,即只看你基準(zhǔn)版本的流量,不看染色的流量,或者將兩個流量的報警場景區(qū)分開。
Q6:如何探測SLO是否已經(jīng)達(dá)到閾值?
A6:SLO的計算本質(zhì)上還是通過Promethues計算,只是報警觸發(fā)的窗口即錯誤預(yù)算窗口和消耗率這兩個概念太難理解,所以我們換成了一個服務(wù)的可用率加一個計算的時間窗口,本質(zhì)還是Promethues來做計算。
Q7:剛開始進(jìn)行SLO建設(shè),如何說服研發(fā)團(tuán)隊配合?
A7:我們內(nèi)部也經(jīng)常遇到這種場景,這個部門出現(xiàn)了一個事故,但沒有報警,就會問能不能用SLO告警覆蓋,感覺SLO是萬能的,然后我們就找研發(fā)團(tuán)隊去聊如何做SLO告警。其實它的前提是首先要定義你的SLI指標(biāo),要看這個業(yè)務(wù)系統(tǒng)要度量什么。對在線服務(wù)來說,可用率是最核心的度量指標(biāo)。但可用率這個指標(biāo)怎么度量,有哪些上報的指標(biāo)可以度量出來?舉個例子,可以通過負(fù)載均衡的指標(biāo)來度量,服務(wù)如果沒有接Promethues的埋點SDK,就無法通過服務(wù)度量。但服務(wù)會打日志,可以通過日志來度量。本質(zhì)來說還是要有指標(biāo),這是第一步。第二步,指標(biāo)一定要能呈現(xiàn)并上報服務(wù)產(chǎn)生的錯誤。
只要滿足這兩個條件,就能做這套系統(tǒng)。它需要服務(wù)標(biāo)準(zhǔn)和微服務(wù)框架的配合,微服務(wù)框架中要有這套指標(biāo)和錯誤,然后才能度量出一個非常精確的SLO系統(tǒng)。其實研發(fā)的配合就是在第一步做指標(biāo)治理這一方面,后續(xù)整個運(yùn)營機(jī)制主要由SRE來建設(shè)。這套系統(tǒng)對研發(fā)來說,能幫助他發(fā)現(xiàn)現(xiàn)象問題,且報警非常準(zhǔn)確,能讓他快速定位線下問題,這樣他一定會主動配合你使用這套系統(tǒng)。
Q8:怎么解決抖動告警?比如每隔幾分鐘 5xx錯誤?
A8:這也是一個很常見的生產(chǎn)的報警模式,分兩種情況看,一種情況是報警很嚴(yán)重,服務(wù)已經(jīng)不可用,必須處理。
另一種情況就是你可以容忍服務(wù)短時間內(nèi)一個5xx,因為這個服務(wù)最近可用性很不好,研發(fā)和我們都知道。那可以調(diào)整報警策略,抑制每幾分鐘產(chǎn)生5xx的條件,比如可以把報警窗口放大,把5分鐘的窗口放大到10分鐘的窗口,5分鐘的可用率存99.9%,你可以把它降為99%,通過新的報警策略去抑制它。
還有一個方法是先靜默一段時間,服務(wù)最近的可能性下跌是一個已知的事實,等把服務(wù)的可能性優(yōu)化之后,再打開報警窗口。
Q9:收到告警之后如何知道具體是哪個錯誤造成的?
A9:可以通過故障定界實現(xiàn)。SLO告警本身只是告警,所以必須與SLO的診斷、可觀測相結(jié)合。因為可觀測觀測的是因,它就是用于發(fā)現(xiàn)服務(wù)的哪些指標(biāo)產(chǎn)生了波動,這些指標(biāo)可能會影響服務(wù)的可用性。但可觀測并沒有告知結(jié)果,并沒有告訴你服務(wù)的可用性下跌,這就是可觀測和SLO的區(qū)別。
可觀測幫助找出原因,SLO讓我們知道結(jié)果,所以SRE里面第二本書的第四章,提及SLO報警的時候,介紹了一個實踐:你有一個SLO的大盤,這個大盤使你得知服務(wù)的SLO產(chǎn)生影響,接下來應(yīng)該告訴研發(fā),服務(wù)的黃金指標(biāo)有哪些,并基于可觀測做成一個大盤,那么這個大盤就可以讓研發(fā)在收到告警之后,快速定位錯誤的原因,做故障的定界。
武安闖
嗶哩嗶哩 SRE負(fù)責(zé)人
先后負(fù)責(zé)中間件運(yùn)維、在線業(yè)務(wù)保障和SRE穩(wěn)定性工程,《2021.07.13 我們是這樣崩的》文章作者。從0到1帶領(lǐng)運(yùn)維向SRE轉(zhuǎn)型,建設(shè)B站穩(wěn)定性體系,主導(dǎo)建設(shè)SRE轉(zhuǎn)型、SLO工程、容量管理體系、高可用架構(gòu)、多活容災(zāi)等專項,當(dāng)前專注于SRE穩(wěn)定性體系規(guī)劃建設(shè)和落地實踐。