对SRE的理解
SRE
這兩年,不同類型、不同規(guī)模的企業(yè) IT 團隊,他們?yōu)榱颂嵘脩魞r值的交付效率,都在積極采用微服務(wù)、容器,以及其他的分布式技術(shù)和產(chǎn)品,而且也在積極引入像 DevOps 這樣的先進理念。
在引入了這么多先進的技術(shù)和理念之后,效率提升了,但這種復(fù)雜架構(gòu)的系統(tǒng)穩(wěn)定性很難得到保障。
這幾年業(yè)界對 SRE 的關(guān)注越來越多,大家也幾乎達成了共識,Google SRE 就是目前穩(wěn)定性領(lǐng)域的最佳實踐。也可以說,SRE 已經(jīng)成為穩(wěn)定性的代名詞。
DevOps和SRE的區(qū)別
DevOps核心是做全棧交付,SRE的核心是穩(wěn)定性保障,關(guān)注業(yè)務(wù)所有活動,兩者的共性是:都使用軟件工程解決問題;
DevOps的誕生是由于互聯(lián)網(wǎng)商業(yè)市場競爭加劇,企業(yè)為減少試錯成本,往往僅推出最小可行產(chǎn)品,產(chǎn)品需要不斷且高頻的迭代來滿足市場需求,搶占市場(產(chǎn)品的迭代是關(guān)乎一整條交付鏈的事),高頻的迭代則會促使研發(fā)團隊使用敏捷模式,敏捷模式下對運維的全棧交付能力要求更嚴(yán)格,則運維必須開啟DevOps來實現(xiàn)全棧交付;因為不斷的迭代交付(也就是俗稱的變更)是觸發(fā)故障的非穩(wěn)定性根源,而互聯(lián)網(wǎng)產(chǎn)品/服務(wù)穩(wěn)定性缺失會造成用戶流失,甚至流到競爭對手那里, 因此關(guān)注業(yè)務(wù)穩(wěn)定性也變得十分重要,SRE由此誕生。
對SRE的理解
SRE 是一套體系化的方法,我們也只有用全局視角才能更透徹地理解它。
從職能分工上,SRE 體系的建設(shè)絕不是單個崗位或單個部門就能獨立完成的,必然要求有高效的跨團隊組織協(xié)作才可以。比如容量評估、故障演練、服務(wù)降級、服務(wù)限流、異常熔斷、監(jiān)控告警等等,這些工作并不是某個人、某個角色,甚至是某個團隊就可以單槍匹馬完成的。比如這里的很多事情要依賴運維自動化,像容量擴縮容,必然會與運維團隊有交集;如果做得再彈性一些,還需要與監(jiān)控結(jié)合,就要與監(jiān)控團隊有合作;同時還可能依賴 DevOps 提供持續(xù)交付、配置變更,以及灰度發(fā)布這些基礎(chǔ)能力,就要與開發(fā)和效能團隊有交集。
SRE的根本目的是為了提高穩(wěn)定性:
從業(yè)界穩(wěn)定性通用的衡量標(biāo)準(zhǔn)看,有兩個非常關(guān)鍵的指標(biāo):
MTBF,Mean Time Between Failure,平均故障時間間隔。
MTTR,Mean Time To Repair, 故障平均修復(fù)時間。
還來看前面的 SRE 穩(wěn)定性保障規(guī)劃圖,你會發(fā)現(xiàn)我們把整個軟件運行周期按照這兩個指標(biāo)分成了兩段。通俗地說,MTBF 指示了系統(tǒng)正常運行的階段,而 MTTR 則意味著系統(tǒng)故障狀態(tài)的階段。
如果想提升穩(wěn)定性,就會有兩個方向:提升 MTBF,也就是減少故障發(fā)生次數(shù),提升故障發(fā)生間隔時長;降低 MTTR,故障不可避免,那就提升故障處理效率,減少故障影響時長。
從 SRE 穩(wěn)定性保障規(guī)劃圖中,可以看出 MTTR 可以細(xì)分為 4 個指標(biāo):MTTI、MTTK、MTTF 和 MTTV。
SRE做的任何一件事情、開發(fā)的任何一套系統(tǒng)、引入的任何一個理念和方法論,有且只有一個目標(biāo),那就是“提升 MTBF,降低 MTTR”,也就是把故障發(fā)生時間的間隔變長,將故障影響的時間減少。
比如,在 Pre-MTBF 階段(無故障階段),我們要做好架構(gòu)設(shè)計,提供限流、降級、熔斷這些 Design-for-Failure 的服務(wù)治理手段,以具備故障快速隔離的條件;還可以考慮引入混沌工程這樣的故障模擬機制,在線上模擬故障,提前發(fā)現(xiàn)問題。
在 Post-MTBF 階段,也就是上一故障剛結(jié)束,開啟新的 MTBF 階段,我們應(yīng)該要做故障復(fù)盤,總結(jié)經(jīng)驗,找到不足,落地改進措施等。
在 MTTI 階段,我們就需要依賴監(jiān)控系統(tǒng)幫我們及時發(fā)現(xiàn)問題,對于復(fù)雜度較高和體量非常大的系統(tǒng),要依賴 AIOps 的能力,提升告警準(zhǔn)確率,做出精準(zhǔn)的響應(yīng)。
同時 AIOps 能力在大規(guī)模分布式系統(tǒng)中,在 MTTK 階段也非常關(guān)鍵,因為我們在這個階段需要確認(rèn)根因,至少是根因的范圍。
系統(tǒng)可用性思考
衡量系統(tǒng)可用性的 2 種方式
- 時間維度:Availability = Uptime / (Uptime + Downtime)
- 請求維度:Availability = Successful request / Total request
時間維度,是從故障角度出發(fā)對系統(tǒng)穩(wěn)定性進行評估,
對應(yīng)到系統(tǒng)上,我們會用一系列的標(biāo)準(zhǔn)和判定邏輯來說明系統(tǒng)是否正常。比如,系統(tǒng)請求狀態(tài)碼為非 5xx 的比例,也就是請求成功率低于 95%,已經(jīng)連續(xù)超過 10 分鐘,這時就要算作故障,那么 10 分鐘就要納入 Downtime(宕機時間),如果達不到這個標(biāo)準(zhǔn),就不算作故障,只是算作一般或偶然的異常問題。
這里有三個要素:衡量指標(biāo),系統(tǒng)請求狀態(tài)碼;衡量目標(biāo),非 5xx 占比,也就是成功率達到 95%;影響時長,持續(xù) 10 分鐘。
針對時長維度的穩(wěn)定性計算方式最顯著的問題就是,穩(wěn)定性只與故障發(fā)生掛鉤。
如有一個系統(tǒng),因為網(wǎng)絡(luò)抖動,有短暫的幾秒、十幾秒,或者幾分鐘異常,但是后來系統(tǒng)自己恢復(fù)了,業(yè)務(wù)并沒有中斷,這時我們按照時長維度來判斷,這肯定不會算作系統(tǒng)故障。但是如果這種短暫的影響頻度非常高,一天來個 5、6 次,持續(xù)一兩周,我們應(yīng)該可以判定系統(tǒng)運行狀況也是不正常的,可能不是故障,但肯定是不穩(wěn)定了。
這種用時長維度來衡量系統(tǒng)穩(wěn)定性的方式,其主要缺點就是粒度不夠精細(xì)。這些小的異常問題和它們的影響,如果從更長的周期來看,也是有一定參考價值的。
第二種衡量方式,也就是從請求維度來衡量系統(tǒng)可用性。用一句話來說,請求維度,是從成功請求占比的角度出發(fā),對系統(tǒng)的穩(wěn)定性進行評估。
假定我們的系統(tǒng)一天內(nèi)有 100,000 次請求,我們期望的成功率至少是 95%,如果有 5001 次請求失敗了,也就是成功率低于 95% 了,我們就認(rèn)為系統(tǒng)運行狀態(tài)是不正常的。
請求維度的系統(tǒng)可用性同樣包含三個關(guān)鍵要素,第一個衡量指標(biāo),請求成功率;第二個衡量目標(biāo),成功率達到 95% 才算系統(tǒng)運行正常;第三個是統(tǒng)計周期,比如一天、一周、一個月等等,我們是在一個統(tǒng)計周期內(nèi)計算整體狀況,而不是看單次的。
這種方式對系統(tǒng)運行狀況是否穩(wěn)定監(jiān)管得更為嚴(yán)格,不會漏掉任何一次問題的影響,因為它對系統(tǒng)整體運行的穩(wěn)定性判定,不僅僅會通過單次的異常影響進行評估,還會累計疊加進行周期性的評估。
到這里,我們就總結(jié)出一條至關(guān)重要的經(jīng)驗了:故障一定意味著不穩(wěn)定,但是不穩(wěn)定,并不意味著一定有故障發(fā)生。
設(shè)定系統(tǒng)穩(wěn)定性目標(biāo)要考慮的 3 個因素
-
成本因素
從理論上來說,肯定是 9 越多穩(wěn)定性越好,但是相應(yīng)付出的成本和代價也會更高。
-
業(yè)務(wù)容忍度
對于核心業(yè)務(wù)或核心應(yīng)用,比如電商的交易和支付系統(tǒng),我們當(dāng)然是希望成功率越高越好,一般對系統(tǒng)穩(wěn)定性要求是“3 個 9”或“4 個 9”。對于非核心業(yè)務(wù)或應(yīng)用,比如商品評論,商品評分等,或許“2 個 9”也能容忍。因為短時間的評論看不到,并不會對業(yè)務(wù)收入和用戶體驗造成太大的影響。
-
系統(tǒng)當(dāng)前的穩(wěn)定性狀況
結(jié)合系統(tǒng)的實際情況,定一個合理的標(biāo)準(zhǔn)比定一個更高的標(biāo)準(zhǔn)會更重要。
SRE 會更多采用請求維度的統(tǒng)計方式,因為 SRE 關(guān)注的穩(wěn)定性是系統(tǒng)的整體運行狀態(tài),而不僅僅只關(guān)注故障狀態(tài)下的穩(wěn)定性,在系統(tǒng)運行過程中的任何異常,都會被納入穩(wěn)定性的評估范疇中。
SRE切入點:選擇SLI,設(shè)定SLO
SRE 強調(diào)的穩(wěn)定性,一般不是看單次請求的成功與否,而是看整體情況,所以我們會把成功請求的占比設(shè)定為一個可以接受的目標(biāo),也就是我們常說的“3 個 9”或“4 個 9”這樣的可量化的數(shù)字。
那么,這個“確定成功請求條件,設(shè)定達成占比目標(biāo)”的過程,在 SRE 中就是設(shè)定穩(wěn)定性衡量標(biāo)準(zhǔn)的 SLI 和 SLO 的過程。具體來看下這兩個概念。
SLI,Service Level Indicator,服務(wù)等級指標(biāo),其實就是我們選擇哪些指標(biāo)來衡量我們的穩(wěn)定性。
SLO,Service Level Objective,服務(wù)等級目標(biāo),指的就是我們設(shè)定的穩(wěn)定性目標(biāo),比如“幾個 9”這樣的目標(biāo)。
落地 SRE 的第一步其實就是“選擇合適的 SLI,設(shè)定對應(yīng)的 SLO”。
我們以電商交易系統(tǒng)中的一個核心應(yīng)用“購物車”為例,給它取名叫做 trade_cart。trade_cart 是以請求維度來衡量穩(wěn)定性的,也就是說單次請求如果返回的是非 5xx 的狀態(tài)碼,我們認(rèn)為該次請求是成功的;如果返回的是 5xx 狀態(tài)碼,如我們常見的 502 或 503,我們就判斷這次請求是失敗的。
在 SRE 實踐中,我們用 SLI 和 SLO 來描述。“狀態(tài)碼為非 5xx 的比例”就是 SLI,“大于等于 99.95%”就是 SLO。說得更直接一點,SLO 是 SLI 要達成的目標(biāo)。
SLI 就是我們要監(jiān)控的指標(biāo),SLO 就是這個指標(biāo)對應(yīng)的目標(biāo)。
選擇 SLI 指標(biāo)的兩大原則:
原則一:選擇能夠標(biāo)識一個主體是否穩(wěn)定的指標(biāo),如果不是這個主體本身的指標(biāo),或者不能標(biāo)識主體穩(wěn)定性的,就要排除在外。
原則二:針對電商這類有用戶界面的業(yè)務(wù)系統(tǒng),優(yōu)先選擇與用戶體驗強相關(guān)或用戶可以明顯感知的指標(biāo)。
還拿我們上面 trade_cart 的例子來說,主體確定了,就是 trade_cart,應(yīng)用層面的,請求返回狀態(tài)碼和時延就是很好的指標(biāo),再來檢查下它們能否標(biāo)識的 trade_cart 穩(wěn)定性,毫無疑問,這兩個指標(biāo)都可以,那么請求返回狀態(tài)碼和時延就可以作為 trade_cart 穩(wěn)定性的 SLI 指標(biāo)。
我們換一個指標(biāo),CPU 的使用率這個指標(biāo)適合嗎?根據(jù)我們剛才說的原則,既然我們關(guān)注的是 trade_cart 的運行狀況,而 CPU 是系統(tǒng)層的指標(biāo),所以,在選擇應(yīng)用層 SLI 的指標(biāo)時,自然會把 CPU 排除掉。
快速識別 SLI 指標(biāo)的方法:VALET:
VALET 是 5 個單詞的首字母,分別是 Volume、Availability、Latency、Error 和 Ticket。這 5 個單詞就是我們選擇 SLI 指標(biāo)的 5 個維度。
Volume- 容量
Volume(容量)是指服務(wù)承諾的最大容量是多少。比如,一個應(yīng)用集群的 QPS(最大吞吐能力)、TPS(服務(wù)器每秒處理的事務(wù)數(shù))、會話數(shù)以及連接數(shù)等等,如果我們對日常設(shè)定一個目標(biāo),就是日常的容量 SLO,對雙 11 這樣的大促設(shè)定一個目標(biāo),就是大促 SLO。對于數(shù)據(jù)平臺,我們要看它的吞吐能力,比如每小時能處理的記錄數(shù)或任務(wù)數(shù)。
Availablity- 可用性
Availablity(可用性)代表服務(wù)是否正常。比如,我們前面介紹到的請求調(diào)用的非 5xx 狀態(tài)碼成功率,就可以歸于可用性。對于數(shù)據(jù)平臺,我們就看任務(wù)的執(zhí)行成功情況,這個也可以根據(jù)不同的任務(wù)執(zhí)行狀態(tài)碼來歸類。
Latency- 時延
Latency(時延)是說響應(yīng)是否足夠快。這是一個會直接影響用戶訪問體驗的指標(biāo)。對于任務(wù)類的作業(yè),我們會看每個任務(wù)是否在規(guī)定時間內(nèi)完成了。
通常對于時延這個指標(biāo),我們不會直接做所有請求時延的平均,因為整個時延的分布也符合正態(tài)分布,所以通常會以類似“90% 請求的時延 <= 80ms,或者 95% 請求的時延 <=120ms ”這樣的方式來設(shè)定時延 SLO,熟悉數(shù)理統(tǒng)計的同學(xué)應(yīng)該知道,這個 90% 或 95% 我們稱之為置信區(qū)間。
因為不排除很多請求從業(yè)務(wù)邏輯層面是不成功的,這時業(yè)務(wù)邏輯的處理時長就會非常短(可能 10ms),或者出現(xiàn) 404 這樣的狀態(tài)碼(可能就 1ms)。從可用性來講,這些請求也算成功,但是這樣的請求會拉低整個均值。
同時,也會出現(xiàn)另一種極端情況,就是某幾次請求因為各種原因,導(dǎo)致時延高了,到了 500ms,但是因為次數(shù)所占比例較低,數(shù)據(jù)被平均掉了,單純從平均值來看是沒有異常的。但是從實際情況看,有少部分用戶的體驗其實已經(jīng)非常糟糕了。所以,為了識別出這種情況,我們就要設(shè)定不同的置信區(qū)間來找出這樣的用戶占比,有針對性地解決。
Errors- 錯誤率
錯誤率有多少?這里除了 5xx 之外,我們還可以把 4xx 列進來,因為前面我們的服務(wù)可用性不錯,但是從業(yè)務(wù)和體驗角度,4xx 太多,用戶也是不能接受的。
或者可以增加一些自定義的狀態(tài)碼,看哪些狀態(tài)是對業(yè)務(wù)有損的,比如某些熱門商品總是缺貨,用戶登錄驗證碼總是輸入錯誤,這些雖不是系統(tǒng)錯誤,但從業(yè)務(wù)角度來看,對用戶的體驗影響還是比較大的。
Tickets- 人工介入
是否需要人工介入?如果一項工作或任務(wù)需要人工介入,那說明一定是低效或有問題的。舉一個我們常見的場景,數(shù)據(jù)任務(wù)跑失敗了,但是無法自動恢復(fù),這時就要人工介入恢復(fù);或者超時了,也需要人工介入,來中斷任務(wù)、重啟拉起來跑等等。
Tickets 的 SLO 可以想象成它的中文含義:門票。一個周期內(nèi),門票數(shù)量是固定的,比如每月 20 張,每次人工介入,就消耗一張,如果消耗完了,還需要人工介入,那就是不達標(biāo)了。
這里給出一個 Google 提供的,針對類似于我們 trade_cart 的一個應(yīng)用服務(wù),基于 VALET 設(shè)計出來的 SLO 的 Dashboard 樣例,
如何通過 SLO 計算可用性?
系統(tǒng)可用性:Availability = Successful request / Total request
第一種,直接根據(jù)成功的定義來計算。
也就是我們前面定義一個請求的返回狀態(tài)碼必須是非 5xx 才算成功,同時時延還要低于 80ms,同時滿足這兩個條件,我們才算是成功的,也就是納入上述公式中 Successful request 的統(tǒng)計中,用公式來表示:
Successful = (狀態(tài)碼非 5xx) & (時延 <= 80ms)
這種計算方式存在的問題就是,對單次請求的成功與否的判定太過死板,容易錯殺誤判。比如我們前面講對于時延,我們一般會設(shè)定置信區(qū)間,比如 90% 時延小于等于 200ms 這樣的場景,用這種方式就很難體現(xiàn)出來。而且,對于狀態(tài)碼成功率和時延成功率的容忍度,通常也是也不一樣的,通過這種方式就不夠準(zhǔn)確。所以,我們就會采取第二種方式。
第二種方式,SLO 方式計算。
SLO1:99.95% 狀態(tài)碼成功率
SLO2:90% Latency <= 80ms
SLO3:99% Latency <= 200ms
直接用公式表示:Availability = SLO1 & SLO2 & SLO3
只有當(dāng)這個三個 SLO 同時達標(biāo)時,整個系統(tǒng)的穩(wěn)定性才算達標(biāo),有一個不達標(biāo)就不算達標(biāo),這樣就可以很好地將 SLO 設(shè)定的合理性與最終可用性結(jié)合了起來。所以,通常在 SRE 實踐中,我們通常會采用這種設(shè)定方式。
Google 的 SLI 和 SLO 設(shè)定模板鏈接:https://landing.google.com/sre/workbook/chapters/slo-document
落地 SLO,先轉(zhuǎn)化為 Error Budget
錯誤預(yù)算其實和駕照記分制是一樣的,最大的作用就是“提示你還有多少次犯錯的機會”,并且,錯誤預(yù)算的警示效果比看成功率這種統(tǒng)計數(shù)據(jù)更直觀,感官沖擊力更強。
以 trade_cart 購物車這個應(yīng)用為例,SLO 目標(biāo)就是我們上節(jié)課定過的。假設(shè)在 4 周的時間,這個應(yīng)用所有的請求次數(shù)是 4,653,680,按照給出的 SLO 反向推導(dǎo),就可以得到容許的錯誤次數(shù),這就是錯誤預(yù)算。
在 SLO 落地實踐時,我們通常就把 SLO 轉(zhuǎn)化為錯誤預(yù)算,以此來推進穩(wěn)定性目標(biāo)達成。
如何應(yīng)用 Error Budget?
1.穩(wěn)定性燃盡圖
在應(yīng)用錯誤預(yù)算的時候,你要考慮設(shè)定一個合理的周期,比如 1 天、1 周或 1 個月。
1 天或 1 周,周期相對較短,我們通常的建議是 4 個自然周,這個周期設(shè)定更合理,這也是谷歌給出的建議。為什么選 4 個自然周,而不是 1 個自然月呢?主要是因為自然月通常會導(dǎo)致跨周的情況出現(xiàn),相比于 4 個自然周,在統(tǒng)計上就要考慮額外的邊界問題。
同時,在考慮定錯誤預(yù)算的時候,還要考慮到部分特殊場景,這個要根據(jù)業(yè)務(wù)特點來定,比如電商會有雙 11 大促活動,有些產(chǎn)品還要考慮春晚互動活動和搶紅包活動,甚至有些社交類產(chǎn)品還要考慮應(yīng)對突發(fā)新聞導(dǎo)致的訪問量激增問題等等,這些場景必然因為訪問量太大而采取很多限流降級的策略,導(dǎo)致更多的請求失敗。
如果這些活動或事件是發(fā)生在某個考核周期內(nèi),這時要考慮放大錯誤預(yù)算的值,特別是瞬時的錯誤或失敗,應(yīng)該要有更大的容忍度,簡單來講就是,特殊情況特殊處理,當(dāng)然最重要的,也要做好特殊保障和應(yīng)對工作。
2. 故障定級
以 trade_cart 購物車為例,結(jié)合 P0~P4 的故障等級設(shè)置,trade_cart 請求成功率 SLO 對應(yīng)的錯誤預(yù)算是 25,000 次,如果一個問題產(chǎn)生的錯誤請求數(shù)超過了 5000 次,也就是錯誤預(yù)算一下就被消耗掉 20% 以上,這時,我們可以把這次故障定為 P2 級。以此類推,如果消耗 30% 以上,我們定為 P1 級,消耗 50% 以上,定為 P0 級等等。
第一,剩余預(yù)算充足或未消耗完之前,對問題的發(fā)生要有容忍度。
第二,剩余預(yù)算消耗過快或即將消耗完之前,SRE 有權(quán)中止和拒絕任何線上變更
此時的情況已經(jīng)說明系統(tǒng)穩(wěn)定出現(xiàn)了很大問題,不能再讓它“帶病工作”。同樣,這時的業(yè)務(wù)開發(fā)團隊,也有權(quán)拒絕新的需求,他們首要的事情,應(yīng)該是跟 SRE 一起解決影響穩(wěn)定性的問題,直至問題解決,且等到下一個周期有了新的錯誤預(yù)算后,再恢復(fù)正常變更節(jié)奏。
日常工作中,作為一線的工程師,你肯定要接收大量的告警短信,但是這些告警里面很大一部分都是沒有實際意義的。為什么這么說呢?因為它們沒有行動指導(dǎo)意義,比如 CPU 使用率 80%、成功率低于 95%、時延超過 80ms 等等,這樣的告警只是告訴我們有問題、有異常,但是否需要高優(yōu)先級馬上處理,還是說可以先放一放、過一會再處理呢?你可能并沒有辦法判斷。這樣的告警,接收的次數(shù)多了,就會變成“狼來了”,你自己變得警惕性不高,當(dāng)故障真的發(fā)生時,你也沒法快速響應(yīng)。
那我們應(yīng)當(dāng)如何做告警收斂呢?從我的經(jīng)驗看,有兩個解決辦法。
- 第一個,相同相似告警,合并后發(fā)送,比如同一應(yīng)用集群內(nèi)同一時間內(nèi),同一異常告警,就先合并,對外只發(fā)送一條,這種比較簡單直接。
- 第二個,基于錯誤預(yù)算來做告警,也就是說我們只關(guān)注對穩(wěn)定性造成影響的告警,比如我們前面提到的,當(dāng)單次問題消耗的錯誤預(yù)算達到 20% 或 30% 等某一閾值時,就意味著問題非常嚴(yán)重了,這種告警信息一旦收到,就要馬上做出響應(yīng)。這樣告警數(shù)量不多,既達到了收斂效果,又非常精準(zhǔn)。
谷歌基于 SLO 和錯誤預(yù)算的幾種告警算法: https://sre.google/workbook/alerting-on-slos/
如何衡量 SLO 的有效性?
衡量 SLO 及錯誤預(yù)算策略是否有效,其實就是看實際運行后,是否真的能達到我們的期望。
我們可以從下面三個關(guān)鍵維度來看。
- SLO 達成情況。我們用達成(Met),或未達成(Missed)來表示。
- “人肉”投入程度。英文表示為 Toil,這里用形象一點的“人肉”投入作為它的譯意,泛指需要大量人工投入、重復(fù)、繁瑣且沒有太多價值的事情。我們用投入程度高(High)和低(Low)來表示。
- 用戶滿意度。英文就是 Customer Satisfaction,可以理解為用戶感受和體驗如何。這個信息可以通過真實和虛擬渠道獲得。真實渠道如客服投訴、客戶訪談和輿情監(jiān)控獲取;虛擬渠道如真機模擬撥測。我們用滿意度高(High)和低(Low)來表示。
總共 3 個維度,每個維度有 2 種情況,組合起來就是 8 種情況,我們直接引用 Google 給出的圖表和建議。
針對這 8 種情況,我們分別給出對應(yīng)策略:
第一類,收緊 SLO。
這個時候就是目標(biāo)定得太低了,比如 SLO 達成(Met),但是用戶不滿意(Low)。這就表示我們的 SLO 設(shè)定得太容易達成,沒有反饋真實的運行狀況。
第二類,放寬 SLO。
與第一類相反,目標(biāo)定太高,總是達不成(Missed),但用戶反饋卻很不錯(High),這種就會造成錯誤預(yù)算提前消耗完,導(dǎo)致很多變更暫停,產(chǎn)品延期,甚至?xí)鲆恍o謂的優(yōu)化,這時就可以適當(dāng)松松綁。
第三類,保持現(xiàn)狀。
對有問題的維度采取有針對性的優(yōu)化措施。比如表格第一行,是我們期望的最理想狀態(tài),SLO 能達成,人肉投入又低,客戶滿意度又很高,也沒有特別的優(yōu)化空間,這時我們就可以增加發(fā)布和變更次數(shù),更大程度地釋放生產(chǎn)力。
總結(jié):
案例:落地SLO時還需要考慮哪些因素?
一般來說,電商系統(tǒng)一定有一個或幾個核心服務(wù),比如要給用戶提供商品選擇、搜索和購買的服務(wù)等。但我們知道,大部分用戶并不是上來就購買,而是會有一個訪問的過程,他們會先登錄,再搜索,然后訪問一個或多個商品詳情介紹,決定是放到購物車候選,還是選擇物流地址后直接下單,最后支付購買。
這條從登錄到購買的鏈路,我們一般稱之為系統(tǒng)的核心鏈路(Critical Path),系統(tǒng)或網(wǎng)站就是依靠這樣一條訪問鏈路,為用戶提供了購買商品的服務(wù)能力。
至于電商系統(tǒng)的其它頁面或能力,比如網(wǎng)站政策、新手指導(dǎo)、開店指南等等,這些對用戶購買服務(wù)不會造成太大影響的,相對于核心鏈路來說,它的重要性就相對低一些。
我們要給電商系統(tǒng)設(shè)定 SLO,大的原則就是先設(shè)定核心鏈路的 SLO,然后根據(jù)核心鏈路進行 SLO 的分解。
核心鏈路:確定核心應(yīng)用與強弱依賴關(guān)系
要確定核心鏈路的 SLO,我們得先找到核心鏈路。
我們可以先通過全鏈路跟蹤這樣的技術(shù)手段找出所有相關(guān)應(yīng)用,也就是呈現(xiàn)出調(diào)用關(guān)系的拓?fù)鋱D,下圖是亞馬遜電商分布式系統(tǒng)的真實調(diào)用關(guān)系拓?fù)鋱D。之所以這么復(fù)雜,是因為即使是單條路徑,它實際覆蓋的應(yīng)用也是很多的,特別是對于大型的分布式業(yè)務(wù)系統(tǒng),可能會有幾十甚至上百個路徑,這些應(yīng)用之間的依賴關(guān)系也特別復(fù)雜。
面對這樣復(fù)雜的應(yīng)用關(guān)系,繼續(xù)來做精簡,也就是區(qū)分哪些是核心應(yīng)用,哪些是非核心應(yīng)用。
比如用戶訪問商品詳情的時候,會同時展現(xiàn)商品評價信息,但是這些信息不展現(xiàn),對于用戶選擇商品也不會造成非常大影響,特別是在雙十一大促這樣的場景中,用戶在這個時刻的目的很明確,就是購買商品,并不是看評價。所以類似商品評價的應(yīng)用是可以降級的,或者短時間不提供服務(wù)。那這種不影響核心業(yè)務(wù)的應(yīng)用就可以歸為非核心應(yīng)用。
相反的,像商品 SKU(庫存)或優(yōu)惠券這樣的應(yīng)用,直接決定了用戶最終的購買金額,這種應(yīng)用在任何時刻都要保持高可用。那這種必須是高可用的應(yīng)用就是核心應(yīng)用。
這張圖就呈現(xiàn)出一條典型的電商交易的關(guān)鍵路徑,其中綠色部分為核心應(yīng)用,藍(lán)色部分為非核心應(yīng)用。
核心應(yīng)用之間的依賴關(guān)系,我們稱之為強依賴,而其它應(yīng)用之間的依賴關(guān)系,我們稱之為弱依賴
設(shè)定 SLO 有哪些原則?
第一,核心應(yīng)用的 SLO 要更嚴(yán)格,非核心應(yīng)用可以放寬。 這么做,就是為了確保 SRE 的精力能夠更多地關(guān)注在核心業(yè)務(wù)上。
第二,強依賴之間的核心應(yīng)用,SLO 要一致。 比如下單的 Buy 應(yīng)用要依賴 Coupon 這個促銷應(yīng)用,我們要求下單成功率的 SLO 要 99.95%,如果 Coupon 只有 99.9%,那很顯然,下單成功率是達不成目標(biāo)的,所以我們就會要求 Coupon 的成功率 SLO 也要達到 99.95% 。
第三,弱依賴中,核心應(yīng)用對非核心的依賴,要有降級、熔斷和限流等服務(wù)治理手段。 這樣做是為了避免由非核心應(yīng)用的異常而導(dǎo)致核心應(yīng)用 SLO 不達標(biāo)。
第四,Error Budget 策略,核心應(yīng)用的錯誤預(yù)算要共享,就是如果某個核心應(yīng)用錯誤預(yù)算消耗完,SLO 沒有達成,那整條鏈路,原則上是要全部暫停操作的,因為對于用戶來說,他不會判斷是因為哪個應(yīng)用有問題,導(dǎo)致的體驗或感受不好。所以,單個應(yīng)用的錯誤預(yù)算消耗完,都要停止變更,等問題完全解決再恢復(fù)變更。當(dāng)然,也可以根據(jù)實際情況適當(dāng)寬松,如果某個核心應(yīng)用自身預(yù)算充足,且變更不影響核心鏈路功能,也可以按照自己的節(jié)奏繼續(xù)做變更。這一點,你可以根據(jù)業(yè)務(wù)情況自行判斷。
如何驗證核心鏈路的 SLO?
梳理出系統(tǒng)的核心鏈路并設(shè)定好 SLO 后,我們需要一些手段來進行驗證。一種是容量壓測,另一種就是 Chaos Engineering,也就是混沌工程。
容量壓測
我們先來看容量壓測。容量壓測的主要作用,就是看 SLO 中的 Volume,也就是容量目標(biāo)是否可以達成。對于一般的業(yè)務(wù)系統(tǒng),我們都會用 QPS 和 TPS 來表示系統(tǒng)容量,得到了容量這個指標(biāo),你就可以在平時觀察應(yīng)用或系統(tǒng)運行的容量水位情況。比如,我們設(shè)定容量的 SLO 是 5000 QPS,如果日常達到 4500,也就是 SLO 的 90%,我們認(rèn)為這個水位狀態(tài)下,就要啟動擴容,提前應(yīng)對更大的訪問流量。
TPS和QPS的區(qū)別:https://blog.csdn.net/a745233700/article/details/117917333
容量壓測的另一個作用,就是看在極端的容量場景下,驗證我們前面說到的限流降級策略是否可以生效。
我們看上面電商交易的關(guān)鍵路徑圖,以 Detail(商品詳情頁)和 Comment(商品評論)這兩個應(yīng)用之間的弱依賴關(guān)系為例。從弱依賴的原則上講,如果 Comment 出現(xiàn)被調(diào)用次數(shù)過多超時或失敗,是不能影響 Detail 這個核心應(yīng)用的,這時,我們就要看這兩個應(yīng)用之間對應(yīng)的降級策略是否生效,如果生效業(yè)務(wù)流程是不會阻塞的,如果沒有生效,那這條鏈路的成功率就會馬上降下來。
另外,還有一種場景,如果某個非核心應(yīng)用調(diào)用 Detail 的次數(shù)突然激增,對于 Detail 來說,它自身的限流保護機制要發(fā)揮作用,確保自己不會被外部流量隨意打垮。
Chaos Engineering- 混沌工程
現(xiàn)在混沌功能非常流行,因為它可以幫助我們做到在線上模擬真實的故障,做線上應(yīng)急演練,提前發(fā)現(xiàn)隱患。很多公司都很推崇這種方法并在積極學(xué)習(xí)落地中。
比如對于機房故障,有些大廠會直接模擬斷電這樣的場景,看機房是否可以切換到雙活或備用機房;在網(wǎng)絡(luò)層面,我們會模擬丟包或網(wǎng)卡流量打滿;硬件和系統(tǒng)層面,可能故意把一塊磁盤寫滿,或者把 CPU 跑滿,甚至直接把一個服務(wù)器重啟;應(yīng)用層面,更多地會做一些故障注入,比如增加某個接口時延,直接返回錯誤異常,線程池跑滿,甚至一個應(yīng)用集群直接下線一半或更多機器等。
其實混沌工程也是一個非常復(fù)雜的系統(tǒng)化工程,因為要在線上制造故障,或多或少都要對線上業(yè)務(wù)造成影響,如果模擬故障造成的真實影響超過了預(yù)估影響,也要能夠快速隔離,并快速恢復(fù)正常業(yè)務(wù)。即使是在穩(wěn)定性體系已經(jīng)非常完善的情況下,對于混沌工程的實施也要極為謹(jǐn)慎小心。對于一個模擬策略上線實施,一定是在一個隔離的環(huán)境中經(jīng)過了大量反復(fù)驗證,包括異常情況下的恢復(fù)預(yù)案實施,確保影響可控之后,在經(jīng)過多方團隊評審或驗證,才最終在線上實施。
混沌工程是 SRE 穩(wěn)定性體系建設(shè)的高級階段,一定是 SRE 體系在服務(wù)治理、容量壓測、鏈路跟蹤、監(jiān)控告警、運維自動化等相對基礎(chǔ)和必需的部分非常完善的情況下才會考慮的。
應(yīng)該在什么時機做系統(tǒng)驗證?
我們有了驗證整個系統(tǒng) SLO 的手段,但是我們可以看到,這兩個手段都是要在生產(chǎn)系統(tǒng)上直接實施的,為了保證我們的業(yè)務(wù)正常運行,那我們應(yīng)該選擇在什么時機,以及什么條件下做系統(tǒng)驗證呢?
核心就是錯誤預(yù)算充足就可以嘗試,盡量避開錯誤預(yù)算不足的時間段。因為在正常業(yè)務(wù)下,我們要完成 SLO 已經(jīng)有很大的壓力了,不能再給系統(tǒng)穩(wěn)定性增加新的風(fēng)險。
同時,我們還要評估故障模擬帶來的影響,比如,是否會損害到公司收益?是否會損害用戶體驗相關(guān)的指標(biāo)?如果造成的業(yè)務(wù)影響很大,那就要把引入方案進行粒度細(xì)化,分步驟,避免造成不可預(yù)估的損失。
團隊通常的做法,就是選擇凌晨,業(yè)務(wù)量相對較小的情況下做演練。這樣即使出現(xiàn)問題,影響面也可控,而且會有比較充足的時間執(zhí)行恢復(fù)操作,同時,在做較大規(guī)模的全站演練前,比如全鏈路的壓測,會做單鏈路和單業(yè)務(wù)的單獨演練,只有單鏈路全部演練通過,才會執(zhí)行更大規(guī)模的多鏈路和全鏈路同時演練。
總之,生產(chǎn)系統(tǒng)的穩(wěn)定性在任何時候,都是最高優(yōu)先級要保證的,決不能因為演練導(dǎo)致系統(tǒng)異常或故障,這也是不被允許的。所以,一定要選擇合適的時機,在有充分準(zhǔn)備和預(yù)案的情況下實施各類驗證工作。
故障發(fā)現(xiàn):如何建設(shè)On-Call機制?
聚焦 MTTR,故障處理的關(guān)鍵環(huán)節(jié)
故障處理的環(huán)節(jié)就是 MTTR,它又細(xì)分為 4 個指標(biāo):MTTI、MTTK、MTTF 和 MTTV,之所以分組分塊,也是為了更加有目的性地做到系統(tǒng)穩(wěn)定性。
故障處理 MTTR 又各自占多長時間呢?下面這個 MTTR 的時長分布圖,是 IBM 在做了大量的統(tǒng)計分析之后給出的。
MTTK 部分,也就是故障定位部分的時長占比最大。這一點,我們應(yīng)該都會有一些共鳴,就是絕大部分的故障,往往只要能定位出問題出在哪兒了,一般都可以快速地解決故障,慢就慢在不知道問題出在哪兒,所以說我們大部分時間都花在尋找問題上了。
但是,在一個分布式的軟件系統(tǒng)下,我們判定一個問題發(fā)生在哪兒,影響范圍到底是怎么樣的,要召集哪些人共同參與定位排查等等,這個反而會消耗更多時間,所以我們看到 MTTI 階段占比會更重。
另外,當(dāng)一個分布式系統(tǒng)發(fā)生故障時,我們的策略一定不是找到根因,而是優(yōu)先恢復(fù)業(yè)務(wù)。所以,我們往往是通過故障隔離的方式,先快速恢復(fù)業(yè)務(wù),也就是我們經(jīng)常聽到的 Design for Failure 這樣的策略,再具體一點,就是服務(wù)限流、降級、熔斷甚至是主備切換這樣的手段,這樣的話,MTTK 的占比會有所下降。
因此,從分布式系統(tǒng)的實際情況來看,整個 MTTR 的時間占比分布大致是這樣的:
MTTI:從發(fā)現(xiàn)故障到響應(yīng)故障
MTTI,就是故障的平均確認(rèn)時間,也就是從故障實際發(fā)生時間點,到觸發(fā)采取實際行動去定位前的這段時間。
這個環(huán)節(jié)其實主要有兩件事情要做:第一件事,判斷出現(xiàn)的問題是不是故障;第二件事,確定由誰來響應(yīng)和召集。
在沒有 SLO 和錯誤預(yù)算這個體系時,我們通常會根據(jù)用戶投訴,或客服對同一問題的重復(fù)反饋來判斷。比如 10 分鐘內(nèi),有超過 50 個用戶投訴無法購買商品、支付不成功或者優(yōu)惠券未生效等問題,我們就會啟動應(yīng)急響應(yīng)。不過,一旦等用戶和客服反饋,就說明故障影響已經(jīng)非常惡劣了,用戶也已經(jīng)處于無法忍受的狀態(tài)了。
顯然這種方式并不高效。既然我們已經(jīng)搭建了 SRE 體系,設(shè)定了 SLO,能對穩(wěn)定性進行量化管理,那我們就能比用戶更快發(fā)現(xiàn)問題并響應(yīng)問題了。至于用戶投訴和客服反饋的渠道,只能是作為我們的輔助手段。
所以,我們可以根據(jù)設(shè)定的 SLO 和錯誤預(yù)算,準(zhǔn)確判斷發(fā)生的問題是否是故障,并依據(jù)故障等級決定我們采取什么樣的措施去處理這些問題,大大提高反應(yīng)效率。
接著來看第二件事,誰來響應(yīng)和召集。這件事很容易理解,如果我們判定這個問題就是一個故障,首先要有人能判定,接下來需要哪些人來介入,并能夠把相關(guān)的人員召集起來,一起來處理故障。
這兩件事,其實就是 SRE 里面提到的 On-Call 機制。
我們可以看到,第一件事其實主要依賴于我們的監(jiān)控和告警體系。這里我想再強調(diào)一下,在 On-Call 階段,并不是所有的告警我們都要響應(yīng),如果不影響穩(wěn)定性,一般的告警是可以降低響應(yīng)級別的,我們只需要響應(yīng)基于 SLO 的告警。
On-Call 的流程機制建設(shè)
1.確保關(guān)鍵角色在線。
這里的關(guān)鍵角色不是指一兩個值班的運維或 SRE 人員,而是整個產(chǎn)品體系中的所有關(guān)鍵角色。比如電商就需要安排核心業(yè)務(wù)應(yīng)用(如用戶、商品、交易、優(yōu)惠及支付等)的 Owner,或 Backup 中至少有一人參與 On-Call 輪班。不過,接收故障告警或第一時間響應(yīng)故障的,一般是運維、PE 或 SRE 這樣的角色,業(yè)務(wù)開發(fā)同事要確保及時響應(yīng) SRE 發(fā)起的故障應(yīng)急。
2.組織 War Room 應(yīng)急組織。
有專門處理故障的“消防群”(暗含著滅火的意思),會將這些關(guān)鍵角色納入其中,當(dāng)有故障發(fā)生時會第一時間在消防群通報,這時對應(yīng)的 On-Call 同事就要第一時間最高優(yōu)先級響應(yīng)呼叫(Page)。如果是工作日,對于嚴(yán)重故障,會立刻組織成立 War Room,責(zé)任人會馬上聚到一起;如果是非工作時間,則會通過電話會議的方式拉起虛擬 War Room。
3.建立合理的呼叫方式。
在 On-Call 的落地過程中,我們經(jīng)常會遇到的一種情況,就是誰最熟悉某個系統(tǒng),誰就最容易被 7*24 小時打擾。比如系統(tǒng)或應(yīng)用的 Owner 或者是架構(gòu)師,出現(xiàn)問題的時候一定是找這些同事處理的效率最高,所以就會造成這些同事被默認(rèn)為 On-Call。
但是這樣做會極大地影響這些同事在正常業(yè)務(wù)開發(fā)上的精力投入。他們要么總是被打斷,要么就是經(jīng)常通宵處理問題,導(dǎo)致第二天無法正常工作,甚至在非工作日也得不到正常的休息。
這種情況下,我們建議使用固定的 On-Call 手機,建立手機與所有 On-Call 系統(tǒng)的對應(yīng)關(guān)系,比如這個手機號碼對應(yīng)交易核心應(yīng)用,另一個號碼對應(yīng) IDC 機房運維等等。這樣我們在 On-Call 時就不再找具體的哪個人,而是手機在誰手中,誰就承擔(dān) On-Call 職責(zé)。除非問題遲遲得不到解決,或者遇到了疑難雜癥,這種時候再呼叫其他同事參與進來。
無論是 SRE、架構(gòu)師,還是一線開發(fā),**熟悉某個系統(tǒng)的最快最好的方式就是參與 On-Call,而不是看架構(gòu)圖和代碼。**所以,有效的 On-Call 機制,可以讓團隊更深刻地認(rèn)識到目前系統(tǒng)的存在哪些問題,對自己的痛苦狀態(tài)也會有更深刻的感受,進而對后面的改進措施才能更有針對性和落地性。同時,On-Call 也可以培養(yǎng)和鍛煉新人和 Backup 角色,這也是讓新人盡快融入團隊和承擔(dān)責(zé)任的最好的方式。
4.確保資源投入的升級機制。
這個跟前面幾條有相關(guān)性,有很多團隊認(rèn)為 On-Call 就是設(shè)置幾個人值班,所有的事情都交給這幾個人做;最極端的還會認(rèn)為所有的事情,都應(yīng)該是沖在最前線的運維或 SRE 來完成。但是,在分布式架構(gòu)這種復(fù)雜場景下,這種思路是明顯不可行的。
這里最核心的一點就是要給到運維和 SRE 授權(quán),當(dāng)他發(fā)現(xiàn)問題不是自己或現(xiàn)有 On-Call 人員能解決的時候,他有權(quán)調(diào)動其他必要資源投入。如果故障等級偏高,一下無法明確具體找哪些人員投入的時候,SRE 或運維可以直接上升到自己的主管或相關(guān)主管那里,要求上級主管協(xié)調(diào)資源投入。必要時,還可以上升到更高級主管,甚至 CTO 或技術(shù) VP 來關(guān)注。所以,授權(quán)非常關(guān)鍵,這一點的具體操作層面,我們會在后面的故障處理過程中再詳細(xì)介紹。
5.與云廠商聯(lián)合的 On-Call。
現(xiàn)在企業(yè)上云是大勢所趨,絕大多數(shù)情況下,我們對問題和故障的處理,是離不開與云產(chǎn)品工程師一起高效聯(lián)動的。所以,我們應(yīng)該把云產(chǎn)品和云廠商作為我們系統(tǒng)的一部分,而不是單純的第三方。而對于云廠商來說,也要考慮把客戶業(yè)務(wù)作為自身業(yè)務(wù)的一部分,只有這樣雙方才能緊密合作。我們應(yīng)該提前做好與云廠商之間的協(xié)作磨合,聯(lián)合故障演練,必要的授權(quán)等等。
故障處理:一切以恢復(fù)業(yè)務(wù)為最高優(yōu)先級
如何建立有效的故障應(yīng)急響應(yīng)機制
比如雙十一這樣的大促活動,團隊的做法一般是空出一個樓層,讓所有參與保障的同事坐在一個樓層辦公。在已經(jīng)形成雙十一文化的阿里,他們把這樣的辦公地點稱為“光明頂”,各大高手齊聚于此,共同保障業(yè)務(wù)和系統(tǒng)穩(wěn)定。
僅僅有 War Room 這樣一個聚集形式還是不夠的,既然我們把解決故障類比成戰(zhàn)爭,我們就一定要有一套相對應(yīng)的指揮體系才可以,這個體系里面,我認(rèn)為最重要的就是“關(guān)鍵角色分工”和“溝通機制”。
關(guān)鍵角色分工:
Incident Commander,故障指揮官,簡稱為 IC。這個角色是整個指揮體系的核心,他最重要的職責(zé)是組織和協(xié)調(diào),而不是執(zhí)行,下面所有的角色都要接受他的指令并嚴(yán)格執(zhí)行。
**Communication Lead,溝通引導(dǎo),簡稱 CL。**負(fù)責(zé)對內(nèi)和對外的信息收集及通報,這個角色一般相對固定,由技術(shù)支持、QA 或者是某個 SRE 來承擔(dān)都可以,但是要求溝通表達能力要比較好。
**Operations Lead,運維指揮,簡稱 OL。**負(fù)責(zé)指揮或指導(dǎo)各種故障預(yù)案的執(zhí)行和業(yè)務(wù)恢復(fù)。
這里其實還有一類角色,雖然不在指揮體系內(nèi),但是也非常重要,我們也要做一下介紹:Incident Responders,簡稱 IR。就是所有需要參與到故障處理中的各類人員,真正的故障定位和業(yè)務(wù)恢復(fù)都是他們來完成的,比如具體執(zhí)行的 SRE、網(wǎng)絡(luò)和系統(tǒng)運維、業(yè)務(wù)開發(fā)、平臺開發(fā)、網(wǎng)絡(luò)或系統(tǒng)運維、DBA,甚至是 QA 等。
流程機制
從我們的實踐經(jīng)驗來看,如果是大范圍的故障,一般就是平臺技術(shù)總監(jiān)或電商業(yè)務(wù)的技術(shù)總監(jiān)來承擔(dān) IC 職責(zé),接下來他就可以從更高的層面組織和協(xié)調(diào)資源投入并有效協(xié)作。這時 SRE 會回歸到 OL 的職責(zé)上,負(fù)責(zé)組織和協(xié)調(diào)具體的執(zhí)行恢復(fù)操作的動作。
反饋機制
沒有進展也是進展,也要及時反饋。比如 10 分鐘之內(nèi)還沒定位結(jié)果,可能我們就會選擇做有損的降級服務(wù),不能讓故障持續(xù)蔓延,這個時候,反饋就顯得尤為重要。
同時,在這個過程中,為了盡量減少對執(zhí)行者的干擾,讓執(zhí)行者能夠更聚焦,我們一般要求團隊 Leader 來收集反饋并傳遞 IC 的指令。CL 也要收集信息,他要做的不是傳達指令,而是在更大范圍內(nèi)同步匯總后的信息,同時還要整理信息傳遞給外部聯(lián)系人。
故障復(fù)盤:黃金三問與判定三原則
故障復(fù)盤黃金三問:
第一問:故障原因有哪些?
第二問:我們做什么,怎么做才能確保下次不會再出現(xiàn)類似故障?
第三問:當(dāng)時如果我們做了什么,可以用更短的時間恢復(fù)業(yè)務(wù)?
具體開復(fù)盤會的時候,就是緊扣著這三問來進行的。除此之外不允許出現(xiàn)相互指責(zé)和埋怨的情況,如果出現(xiàn),會議主持者要及時控制并打斷。會議主持者這個角色,一般情況下,跟我們上一講提到的 CL(Communication Lead),也就是“溝通引導(dǎo)”是一個角色,在公司內(nèi)部叫技術(shù)支持。
故障判定的三原則
通過黃金三問,我們找到了故障發(fā)生的原因,也明確了做什么可以優(yōu)化,那接下來就是落地了。要落地,就要明確到底應(yīng)該由誰來承擔(dān)主要的改進職責(zé)。注意,這里我沒有用誰應(yīng)該承擔(dān)主要責(zé)任,而是承擔(dān)主要的改進職責(zé),也就是由誰來執(zhí)行改進措施。
這個原則是說每個部件自身要具備一定的自愈能力,比如主備、集群、限流、降級和重試等等。例如,在 B 依賴 A 的狀態(tài)下,被依賴方 A 出現(xiàn)問題,但是能夠快速恢復(fù),而依賴方 B 無法快速恢復(fù),導(dǎo)致故障蔓延。這時,承擔(dān)主要責(zé)任的是依賴方 B,而不是被依賴方 A。
服務(wù)器和網(wǎng)絡(luò)類故障,其實就適用這個原則。如交換機故障發(fā)生主備切換導(dǎo)致的網(wǎng)絡(luò)瞬時或短暫抖動,從網(wǎng)絡(luò)設(shè)備這個組件來說,自身是有自愈能力的,而且在極短的時間內(nèi)就可以恢復(fù)。如果應(yīng)用因為抖動而失敗、無法自愈,這種情況,業(yè)務(wù)應(yīng)用就不能以服務(wù)器或網(wǎng)絡(luò)故障為理由,不承擔(dān)改進職責(zé)。
再比如,我們之前講的強弱依賴問題。原則上,核心應(yīng)用對非核心應(yīng)用的依賴必須要有降級和限流手段。如果因為非核心應(yīng)用的故障或者瞬時高并發(fā)訪問,導(dǎo)致核心應(yīng)用故障,這種情況下,主要的改進責(zé)任在核心應(yīng)用,非核心應(yīng)用只需要配合改造。
如果使用到了第三方的服務(wù),如公有云的各類服務(wù),包括 IaaS、PaaS、CDN 以及視頻等等,我們的原則就是默認(rèn)第三方無責(zé)。
這種涉及第三方服務(wù)的情況,在判定改進責(zé)任時會分為兩部分,對內(nèi)誰的服務(wù)受影響誰改進,并對外推進第三方改進,但是一定要按照我們之前講的,穩(wěn)定性一定要做到相對自我可控,而不是完全依賴外部。
比如,一個應(yīng)用使用了 CDN 服務(wù),如果一家 CDN 廠商服務(wù)出現(xiàn)問題,要做到隨時可以切換到另外一到兩家,這時就不能以某家 CDN 服務(wù)故障為由不做改進。如果用到了云存儲,如 S3、OSS 或 COS 這樣的服務(wù),一定要保證存儲有主備,當(dāng)一個區(qū)域有問題時,也要做到可切換,甚至容忍一定的業(yè)務(wù)有損,但是必須保障全量沒有大問題。
如果再提升下高可用視角,就要考慮做到雙活或多活,單個 Zone 甚至單個 Region 出現(xiàn)問題時,也能做到切換。
對內(nèi),默認(rèn)第三方無責(zé),穩(wěn)定性責(zé)任一定是內(nèi)部角色承擔(dān),這樣做有時看起來雖然不太合理,但這樣做的目的,就是讓內(nèi)部意識到穩(wěn)定性和高可用一定是我們自己的責(zé)任,決不能依賴任何一個第三方。這就相當(dāng)于一個國家的軍事國防,可以跟外部形成統(tǒng)一戰(zhàn)線,可以做聯(lián)合演習(xí)共同防御,但是絕不可能完完全全交給另外一個國家去建設(shè)和控制。
這個原則主要應(yīng)用在情況比較復(fù)雜的場景。當(dāng)發(fā)生衍生故障,或者故障蔓延的原因與觸發(fā)原因不同時,我們會將一次故障分段判斷。這樣分段判定會讓故障問題更聚焦,改進措施也會更有針對性。
案例:互聯(lián)網(wǎng)典型的SRE組織架構(gòu)是怎樣的?
這是蘑菇街基于微服務(wù)和分布式技術(shù)的 High-Level 的架構(gòu)圖,也是非常典型的互聯(lián)網(wǎng)技術(shù)架構(gòu)圖,自下而上共四層,分別是基礎(chǔ)設(shè)施層、業(yè)務(wù) & 技術(shù)中臺層、業(yè)務(wù)前臺層以及接入層,在右側(cè)還有一個技術(shù)保障體系。
在講 SRE 的組織架構(gòu)之前,我們需要先明確兩點內(nèi)容。
第一,組織架構(gòu)要與技術(shù)架構(gòu)相匹配。
技術(shù)架構(gòu)實現(xiàn)組織目標(biāo),組織架構(gòu)服務(wù)并促成技術(shù)架構(gòu)的實現(xiàn),所以,我們不會單純?nèi)ブv組織架構(gòu),一定會結(jié)合著技術(shù)架構(gòu)的現(xiàn)狀和演進過程來分析。
第二,SRE 是微服務(wù)和分布式架構(gòu)的產(chǎn)物。
SRE 這個崗位,或者說這個通過最佳實踐提煉出來的方法論,就是在 Google 這樣一個全球最大的應(yīng)用分布式技術(shù)的公司產(chǎn)生出來的。
正是因為分布式技術(shù)的復(fù)雜性,特別是在運維層面的超高復(fù)雜性,才產(chǎn)生了對傳統(tǒng)運維模式和理念的沖擊和變革。
如果我們?nèi)ナ崂硪幌抡麄€軟件架構(gòu)發(fā)展的歷程,就可以得到下面這張圖。我們會發(fā)現(xiàn)不僅僅是 SRE 和 DevOps,就連容器相關(guān)的技術(shù),持續(xù)交付相關(guān)的方法和理念,也是在微服務(wù)架構(gòu)不斷流行的趨勢下所產(chǎn)生的,它們的產(chǎn)生就是為了解決在這種架構(gòu)下運維復(fù)雜度過高的問題。
這樣一套架構(gòu)方法體系,也構(gòu)成了現(xiàn)在非常流行和火熱的概念:云原生架構(gòu)。
基本所有的 SRE 經(jīng)驗都是基于微服務(wù)和分布式架構(gòu)的,也都是在這樣一個基礎(chǔ)下產(chǎn)生的。**想要引入 SRE 體系,并做對應(yīng)的組織架構(gòu)調(diào)整,首先要看我們的技術(shù)架構(gòu)是不是在朝著服務(wù)化和分布式的方向演進。**如果架構(gòu)還沒這么復(fù)雜,其實也沒有必要引入 SRE 這么復(fù)雜的運維體系,這本身就不匹配;再就是如果沒有對應(yīng)的架構(gòu)支持,SRE 技術(shù)層面的建設(shè)就沒有切入點,想做也沒法做。
總的來說,如果我們的技術(shù)架構(gòu)朝著微服務(wù)和分布式的方向演進,那我們可以考慮落地 SRE,這時候,我們的組織架構(gòu)就要匹配我們的技術(shù)架構(gòu),也就是說,要想在組織內(nèi)引入并落地 SRE 這套體系,原有技術(shù)團隊的組織架構(gòu),或者至少是協(xié)作模式必須要做出一些變革才可以。
蘑菇街的 SRE 組織架構(gòu)實踐
先看最下面的基礎(chǔ)設(shè)施層,我們現(xiàn)在也定義為 IaaS 層,主要是以資源為主,包括 IDC、服務(wù)器、虛擬機、存儲以及網(wǎng)絡(luò)等部分。
這里基礎(chǔ)設(shè)施層和所需的運維能力,其實就是我們常說的傳統(tǒng)運維這個角色所要具備的能力。但是這一層現(xiàn)在對于絕大多數(shù)的公司,無論在資源層面還是在能力層面,都有很大的可替代性。如果能夠依托云的能力,不管是公有云還是私有云,這一部分傳統(tǒng)運維的能力在絕大部分公司,基本就不需要了。
接下來往上,我們來看中臺這一層。這里包括兩部分,技術(shù)中臺和業(yè)務(wù)中臺。
技術(shù)中臺主要包括我們使用到的各種分布式部件,如緩存、消息、數(shù)據(jù)庫、對象存儲以及大數(shù)據(jù)等產(chǎn)品,這一層最大的特點就是“有狀態(tài)” ,也就是要存儲數(shù)據(jù)的產(chǎn)品。
業(yè)務(wù)中臺層,就是將具有業(yè)務(wù)共性的產(chǎn)品能力提煉出來,比如用戶、商品、交易、支付、風(fēng)控以及優(yōu)惠等等,上面支撐的是業(yè)務(wù)前臺應(yīng)用。
什么是業(yè)務(wù)前臺呢?如果以阿里的產(chǎn)品體系來舉例,可以類比為淘寶、天貓、盒馬、聚劃算這樣的業(yè)務(wù)產(chǎn)品。
無論這些業(yè)務(wù)前臺的形態(tài)是什么樣,但是都會利用到中臺這些共享能力。這兩層就是微服務(wù)化形態(tài)的業(yè)務(wù)應(yīng)用了,這些應(yīng)用最大的特點就是“無狀態(tài)”,有狀態(tài)的數(shù)據(jù)都會沉淀到剛才提到的技術(shù)中臺的產(chǎn)品中。
最上面是接入層,分為四層負(fù)載均衡和七層負(fù)載均衡。前者因為跟業(yè)務(wù)邏輯不相關(guān),所以通常會跟基礎(chǔ)設(shè)施層放在一起,由傳統(tǒng)運維負(fù)責(zé)。但是七層負(fù)載需要做很多業(yè)務(wù)層面的規(guī)則配置,所以通常會跟中臺和前臺一起運維。
業(yè)務(wù)中臺和前臺這兩層的運維職責(zé),通常就是我們常說的應(yīng)用運維、PE(Production Engineer)或者叫技術(shù)運營這樣的角色來承擔(dān)。團隊是統(tǒng)一用 PE 來代表的。
其實這里 PE 的職責(zé)跟我們前面講的 SRE 的職責(zé)已經(jīng)非常接近了。在國內(nèi),PE 這個角色與 Google 定義的 SRE 所具備的能力,最大差別就在于國內(nèi) PE 的軟件工程能力有所缺失或相對較弱。這就導(dǎo)致很多基于技術(shù)中臺的自動化工具、服務(wù)治理以及穩(wěn)定性保障類的平臺沒辦法自己研發(fā),需要由另外一個團隊來支撐和彌補,也就是圖中技術(shù)中臺的衍生部分,技術(shù)保障體系。
技術(shù)保障平臺,這部分的能力一定基于技術(shù)中臺的能力之上生長出來的,是技術(shù)中臺的一部分,如果脫離了這個架構(gòu)體系,這個技術(shù)保障體系是沒有任何意義的。“運維能力一定是整個技術(shù)架構(gòu)能力的體現(xiàn),而不是單純的運維的運維能力體現(xiàn)”。微服務(wù)和分布式架構(gòu)下的運維能力,一定是跟整個架構(gòu)體系不分家的。
回到技術(shù)保障體系的建設(shè)上,我們看下架構(gòu)圖的右側(cè),它又分為效率和穩(wěn)定兩塊。
工具平臺團隊,負(fù)責(zé)效能工具的研發(fā),比如實現(xiàn) CMDB、運維自動化、持續(xù)交付流水線以及部分技術(shù)運營報表的實現(xiàn),為基礎(chǔ)運維和應(yīng)用運維提供效率平臺支持。
這個要更多地介入到研發(fā)流程中,因為流程復(fù)雜度比較高,而且還要對接很多研發(fā)平臺,如 Git、Maven、代碼掃描、自動化測試以及安全等平臺,所以對業(yè)務(wù)理解及系統(tǒng)集成能力要比較強,但是技術(shù)能力要求相對就沒那么高。
穩(wěn)定性平臺團隊,負(fù)責(zé)穩(wěn)定性保障相關(guān)的標(biāo)準(zhǔn)和平臺,比如監(jiān)控、服務(wù)治理相關(guān)的限流降級、全鏈路跟蹤、容量壓測和規(guī)劃。我們會看到這個團隊主要是為穩(wěn)定性保障提供支撐,平臺提供出來的能力是可以直接支撐業(yè)務(wù)開發(fā)團隊的,反倒是 PE 這樣的角色并不會直接使用。
這個團隊和人員的技術(shù)能力要求會比較高,因為這里面很多的技術(shù)點是要深入到代碼底層的,比如 Java 的字節(jié)碼或 Socket 網(wǎng)絡(luò);有時還要面對海量數(shù)據(jù),以及低時延實時計算的處理,比如全鏈路跟蹤和監(jiān)控;甚至是門檻更高的 AIOps,還要懂專業(yè)算法。所以這個團隊的建設(shè)復(fù)雜度會比較高,會需要很多不同領(lǐng)域的專業(yè)人員。
如果我們用一張組織架構(gòu)圖來展示的話,基本形態(tài)就是下圖:
SRE 并不是一個單純的崗位定義,它是由多個不同角色組合而成的一個團隊。如果從分工來看就是:
SRE = PE + 工具平臺開發(fā) + 穩(wěn)定性平臺開發(fā)
同時,這里的 SRE,跟我們前面講的運維和架構(gòu)不分家一樣,在組織架構(gòu)上,是與承擔(dān)技術(shù)中臺或分布式架構(gòu)建設(shè)的中間件團隊在同一個體系中的。
組織架構(gòu)往往是與技術(shù)架構(gòu)相匹配的,技術(shù)上如果朝著分布式和微服務(wù)架構(gòu)的方向演進,那必然會產(chǎn)生出類似的組織模式。
經(jīng)驗:都有哪些高效的SRE組織協(xié)作機制?
在互聯(lián)網(wǎng)企業(yè)典型的 SRE 團隊中,一般包含幾個關(guān)鍵角色,PE、工具開發(fā)和穩(wěn)定性開發(fā),他們分別承擔(dān)的職責(zé)就是業(yè)務(wù)運維、建設(shè)運維自動化平臺和建設(shè)穩(wěn)定性平臺。在建設(shè)這些平臺的過程中,這些角色對內(nèi)要與中間件團隊合作,基于微服務(wù)和分布式的架構(gòu)來開發(fā)各類平臺;對外,還要與業(yè)務(wù)開發(fā)配合,將提升效率和穩(wěn)定性的能力提供出去。
但是僅僅有組織架構(gòu),有了隊形還是不夠的,各個團隊和角色之間必須要配合協(xié)作起來才能發(fā)揮出 SRE 的作用,特別是對外與業(yè)務(wù)開發(fā)的合作,這樣才能是一個有機的整體。
以賽帶練
類似的場景,比如說極端的海量用戶訪問,像電商類產(chǎn)品的雙十一大促、社交類產(chǎn)品在春晚的搶紅包,以及媒體類產(chǎn)品的突發(fā)熱點新聞等等,用戶瞬時訪問的流量是極大的,對于系統(tǒng)的穩(wěn)定性沖擊和挑戰(zhàn)也就非常大。再或者,是極端的故障場景,比如機房斷電、存儲故障或核心部件失效等等。
所以,我們講穩(wěn)定性建設(shè),一定也是針對極端場景下的穩(wěn)定性建設(shè)。
其實我們有很多的穩(wěn)定性保障技術(shù)和理念,比如容量規(guī)劃和壓測、全鏈路跟蹤、服務(wù)治理、同城雙活甚至是異地多活等,基本都是在這些場景下催生出來的,甚至是被倒逼出來的。
“以賽帶練”的目的就是要檢驗我們的系統(tǒng)穩(wěn)定性狀況到底如何,我們的系統(tǒng)穩(wěn)定性還有哪些薄弱點。
SRE 的各個角色如何協(xié)作?
第一步,大促項目開工會。
在這個會議上,我們會明確業(yè)務(wù)指標(biāo),指定大促項目的技術(shù)保障負(fù)責(zé)人,通常由經(jīng)驗豐富的業(yè)務(wù)技術(shù)成員或平臺技術(shù)成員承擔(dān),同時會明確技術(shù)團隊的分工以及各個團隊的接口人,然后根據(jù)大促日期,倒排全鏈路壓測計劃。分工和計劃敲定了,接下來就是一步步執(zhí)行了。
第二步,業(yè)務(wù)指標(biāo)分解及用戶模型分析評審會。
業(yè)務(wù)指標(biāo)分解和用戶模型分析階段,需要業(yè)務(wù)開發(fā)和 PE 團隊共同配合,主要是共同分析出核心鏈路,同時 PE 要分析鏈路上的應(yīng)用日常運行情況,特別是 QPS 水位,這里就要利用到我們前面 03 講中示例的 SLO 的 Dashboard,結(jié)合這兩點,大致判斷出要擴容的資源需求。
每個 PE 是要負(fù)責(zé)一整條核心鏈路上的應(yīng)用的,所以 PE 可以識別出更全局的鏈路以及整條鏈路上的容量水位情況。而每位業(yè)務(wù)開發(fā)往往只專注在某幾個應(yīng)用上,所以他可以把業(yè)務(wù)目標(biāo)拆解得更細(xì)致,并轉(zhuǎn)化成 QPS 和 TPS 容量要求,然后分配到一個個具體應(yīng)用上,并且每個應(yīng)用的 Owner 在后面要確保這些應(yīng)用能夠滿足各自的 QPS 和 TPS 容量要求。
PE 會更多地從全局角度關(guān)注線上真實的運行狀態(tài),而業(yè)務(wù)開發(fā)則根據(jù)這些信息做更細(xì)致的分析,甚至是深入到代碼層面的分析。
同時,業(yè)務(wù)開發(fā)和 PE 在分析的時候,就要使用到穩(wěn)定性開發(fā)團隊提供的全鏈路跟蹤和監(jiān)控平臺了,而不是靠手工提取日志來做統(tǒng)計分析。
接下來,根據(jù)容量評估的結(jié)果,由 PE 準(zhǔn)備擴容資源,然后業(yè)務(wù)開發(fā)的應(yīng)用 Owner,通過運維自動化平臺,做完全自動化的應(yīng)用部署和服務(wù)上線即可,整個過程無需 PE 介入。
第三步,應(yīng)急預(yù)案評審會。
在預(yù)案準(zhǔn)備階段,仍然是 PE 與業(yè)務(wù)開發(fā)配合,針對核心鏈路和核心應(yīng)用做有針對性的預(yù)案討論。這時就要細(xì)化到接口和方法上,看是否準(zhǔn)備好限流、降級和熔斷策略,策略有了還要討論具體的限流值是多少、降級和熔斷的具體條件是怎樣的,最后這些配置值和配置策略都要落到對應(yīng)的穩(wěn)定性配置中心管理起來。
這里 PE 更多地是負(fù)責(zé)平臺級的策略,比如,如果出現(xiàn)流量激增,首先要做的就是在接入層 Nginx 做限流,并發(fā) QPS 值要設(shè)定為多少合適;再比如緩存失效是否要降級到數(shù)據(jù)庫,如果降級到數(shù)據(jù)庫,必然要降低訪問 QPS,降低多少合適,等等。
而業(yè)務(wù)開發(fā)則要更多地考慮具體業(yè)務(wù)邏輯上的策略,比如商品評論應(yīng)用故障,是否可以直接降級不顯示;首頁或詳情頁這樣的核心頁面,是否在故障時可以完全實現(xiàn)靜態(tài)化等等。
第四步,容量壓測及復(fù)盤會。
在容量壓測這個階段,就需要 PE、業(yè)務(wù)開發(fā)和穩(wěn)定性平臺的同學(xué)來配合了。業(yè)務(wù)開發(fā)在容量規(guī)劃平臺上構(gòu)造壓測數(shù)據(jù)和壓測模型,穩(wěn)定性平臺的同學(xué)在過程中要給予配合支持,如果有臨時性的平臺或工具需求,還要盡快開發(fā)實現(xiàn)。
壓測過程會分為單機、單鏈路和全鏈路幾個環(huán)節(jié),PE 和業(yè)務(wù)開發(fā),在過程中結(jié)合峰值數(shù)據(jù)做相應(yīng)的擴容。如果是性能有問題,業(yè)務(wù)開發(fā)還要做代碼和架構(gòu)上的優(yōu)化,同時,雙方還要驗證前面提到的服務(wù)治理手段是否生效。
壓測過程中和每次壓測結(jié)束后,都要不斷地總結(jié)和復(fù)盤,然后再壓測驗證、擴容和調(diào)優(yōu),直至容量和預(yù)案全部驗證通過。這個過程一般要持續(xù) 2~3 輪,時間周期上要 3~4 周左右。整個過程就會要求三個角色必須要非常緊密地配合才可以。
SRE 組織中的各個角色平時應(yīng)該要做些什么呢?
**第一項,核心應(yīng)用變更及新上線業(yè)務(wù)的穩(wěn)定性評審工作。**這里就包括前面講到的容量評估和壓測、預(yù)案策略是否完備等工作。PE 會跟業(yè)務(wù)開發(fā)一起評估變動的影響,比如變動的業(yè)務(wù)邏輯會不會導(dǎo)致性能影響,進而影響容量;對于新增加的接口或邏輯,是否要做限流、降級和熔斷等服務(wù)治理策略,如果評估出來是必需的,那上線前一定要把這些策略完善好;同時在測試環(huán)境上還要做驗證,上線后要關(guān)注 SLO 是否發(fā)生變化等。
**第二項,周期性技術(shù)運營工作。**這些就包括了我們要例行關(guān)注錯誤預(yù)算的消耗情況,每周或每月輸出系統(tǒng)整體運行報表,并召集業(yè)務(wù)開發(fā)一起開評審會,對變化較大或有風(fēng)險的 SLO 重點評估,進而確認(rèn)是否要采取改進措施或暫停變更,以此來驅(qū)動業(yè)務(wù)開發(fā)關(guān)注和提升穩(wěn)定性。
這里的技術(shù)運營工作,是 PE 職責(zé)非常大的轉(zhuǎn)變,因為隨著各類平臺的完善,很多原來依賴運維完成的事情,業(yè)務(wù)開發(fā)完全可以依賴平臺自主完成,無需運維介入。比如代碼發(fā)布、配置變更,甚至是資源申請。
所以,這時我們會更強調(diào) PE 從全局角度關(guān)注系統(tǒng),除了穩(wěn)定性,還可以關(guān)注資源消耗的成本數(shù)據(jù),在穩(wěn)定和效率都有保證的前提下,也能夠做到成本的不斷優(yōu)化。這樣也會使得 PE 從原有繁瑣的事務(wù)中抽離出來,能夠去做更有價值的事情。
引用:https://time.geekbang.org/column/intro/100048201?tab=catalog
總結(jié)
- 上一篇: DB2 9表分区
- 下一篇: 基于AT89C52单工串行通信系统设计