一、為什麼要做穩定性建設 1、從熵增定律引出穩定性建設的必要性 物理學上,用“熵”來描述一個體系的混亂程度。卡爾·弗里德曼提出熵增定律,他認為在一個封閉的系統內,如果沒有外力的作用,一切物質都會從有序狀態向無序狀態發展。 如果我們不希望系統變混亂,有什麼辦法呢?答案是對抗熵增定律,對抗熵增定律的方法 ...
物理學上,用“熵”來描述一個體系的混亂程度。卡爾·弗里德曼提出熵增定律,他認為在一個封閉的系統內,如果沒有外力的作用,一切物質都會從有序狀態向無序狀態發展。
如果我們不希望系統變混亂,有什麼辦法呢?答案是對抗熵增定律,對抗熵增定律的方法是藉助外力,讓系統從混亂回歸有序。舉個例子:
下圖中,我們使用“熵”值來衡量“骰子系統”的混亂程度,1(最大值)表示“最混亂”,意味著我們不能控制“投骰子”的結果,每次投骰子的結果會在1~6隨機出現,系統表現不穩定;1/6(最小值)表示“最有序”,意味著我們能夠控制“投骰子”的結果,系統表現穩定,比如我們希望每次投篩子的結果都是6,我們可以引入作弊手段(即藉助外力),讓每次投骰子結果都是6。
熵增定律同樣適合軟體系統,一個軟體系統剛發佈時是有序的,熵值趨於1,隨著不斷迭代,慢慢變成混亂的、脆弱的,從而導致線上問題頻發,熵值趨於0,我們需要藉助外力,即穩定性治理手段,提高系統熵值,讓系統恢復穩定。
2、穩定性建設的意義
如下圖分析,系統不穩定會產生真金白銀的損失,因此,穩定性建設的意義是:不是讓業務多掙錢,而是讓業務不丟錢!
3、穩定性衡量公式
① 公式
通過如下公式衡量系統穩定性:Availability = MTTF / (MTTF + MTTR)
②公式說明
MTTF (Mean Time To Failure,平均無故障時間),指系統無故障運行的平均時間,取所有從系統開始正
常運行到發生故障之間的時間段的平均值,即:MTTF =ΣT1/ N。
MTTR (Mean Time To Repair,平均修複時間),指系統從發生故障到維修結束之間的時間段的平均值,即:
MTTR =Σ(T2+T3)/ N。
③公式量化
通常是“SLA是幾個9”去衡量,對應下表:
④常見問題
問題:SLA應該按照哪個維度去定義?介面、應用、業務?
答:都可以,只要講清楚是介面SLA,還是應用SLA,還是業務SLA就可以。但註意:提到應用SLA,應該等於核心介面的最差SLA;提到業務SLA應該等於黃金鏈路的最差SLA。
問題:SLA時間計算周期應該多少?
答:都可以,主要講清楚計算周期就可以,一般以年為單位更具代表性。
4、常見誤區
①不要認為“分散式環境是穩定的”
認為:網路是可靠的,帶寬是無限的,網路的拓撲不會變,延時為0,傳輸開銷為0
實際:網路會抖動,帶寬有上限,存在down機導致的拓撲變化,存在響應超時的概率,等等。
②不要有“確定性思維”,要有“不確定思維”
認為:遵守經驗法則,if x then y。舉例:我見過天鵝是白色的,所以世界上所有天鵝都是白色的;這個系統一直運行良好,所以未來也不會有問題。
應該:世界是不確定的,if x then maybe y。舉例:天鵝還有黑色的。
③不要“甩鍋”,要有“主人翁精神”
認為:故障是因為他們系統掛了,我們只需要打電話通知一下,慢慢等著恢復就行。
應該:提前思考依賴系統故障了,我們如何讓我們用戶儘可能地正常運行;故障出現了,共同想辦法解決問題。
1、技術現狀
互聯網的發展,帶來越來越大的流量,為了支撐越來越大的流量,架構也一直在演進:單體應用架構 -> 垂直應用架構 -> 分散式架構 -> SOA架構 -> 微服務架構 -> 服務網格。當前流行的微服務架構中,在應用層面、基建層面上都會有一些保障穩定性的機制:
-
應用層面的穩定性保障機制
以SpringCloud全家桶為例,提供了很多組件,幫助我們保障系統穩定性,如下圖:
-
基建層面的穩定性保障機制
基建層面上,也會有一些穩定性保障機制,如下表:
分類 | 中間件 | 穩定性設計 |
---|---|---|
中間件 | MySQL | CPU監控,及時超負載情況;慢SQL監控機制,及時發現高危行為。 |
MQ | MQ積壓監控機制,及時發現負載情況;死信處理能力,隔離異常數據和正常數據。 | |
其他 | — | |
基礎設置 | Kubernetes | 動態擴容機制,業務高峰多一些機器,低峰少一些機器;無損上線機制,避免上線過程的PV_LOST。 |
機器監控 | 對機器CPU、記憶體、磁碟進行監控,及時發現機器故障 |
根據所見所聞,當前技術團隊做穩定性治理一般採用如下2種方法:
-
運動式的搞一波穩定性建設
當線上故障頻發,通常會搞個“穩定性治理專項”,定義一些治理點,並給出方案,然後運動式的搞一波。一般經過治理後,穩定性會明顯好轉,但是由於是運動式的搞,隨著業務不斷迭代,根據“熵增定律”, 穩定性又變差。
缺點:不能閉環的搞,治理時穩定性好轉,不治理時穩定性變差,給人感覺技術團隊一直出問題。
-
點狀的搞,針對每個點專項閉環治理
比如搞個“慢SQL治理專項”,通過監控平臺發現慢SQL,給研發發工單,並考核時效;比如搞個“限流治理專項”,讓所有介面配置限流參數,配置限流告警策略。
缺點:研發會感覺穩定性專項很多,也不清楚價值,有時候會應付了事,達不到穩定性治理的目標。
將穩定性建設分為3個階段:事前預防,事中止損,事後復盤,針對這3個階段,建設思路分別是:
1、事前預防
穩定性建設本質上是對抗熵增原理的過程,具體是通過一些技術手段(比如超時治理、限流治理、降級治理、慢SQL等),提前對系統可能出現的故障,建設應對措施,從而讓系統按照設計目標去運行。
註意:穩定性治理的手段很多,每落實一種治理手段,穩定性就能提升一點,可以列出所有已知的治理手段,然後按照優先順序逐個治理。
2、事中止損
按照穩定性衡量公式(如下圖),降低T2或T3可以提升SLA,因此,出現故障後,應該儘可能地降低T2和T3。降低T2的方法是儘快發現系統出現故障,需要依賴監控和告警能力;降低T3的方法是儘快解決問題,需要先止損後找原因,需要一套明確的SOP提高效率。
3、事後復盤
復盤的目標不是定責,而是為避免再犯,因此,在復盤過程中要追到直接原因和根本原因,這2者有很大區別:直接原因指的是因果關係,表達“因為幹了什麼,所以導致什麼”;根本原因是流程規範、認知迭代層面的問題,比如“因為分支規範不是master上線,導致上丟代碼,如果改用gitflow則能夠能夠完全避免上丟代碼的問題”。
關於直接原因和根本原因的舉例:陳勝吳廣起義,直接原因是:下大雨,可能會遲到,遲到要殺頭,所以造反了;根本原因是:秦朝嚴苛的制度,即使沒有那場雨,即使沒有陳勝吳廣,也會有下一場雨,下一個張勝某廣,因為別的原因進行起義。
如上一章節所述,當我們從“事前預防,事中止損,事後復盤”的角度去挖掘穩定性治理手段,會發現有很多業界流行的手段,比如超時治理、限流治理、系統隔離、常態化壓測、慢SQL治理等等。
然而技術資源永遠有限,能夠拿出15%的比例做穩定性治理,已經很不錯了;另外,業務的不同發展階段需要的穩定性手段不一樣,不同穩定性治理手段的ROI也不一樣,因此,我們需要回答一個問題:在有限的研發資源下,如何去按部就班的去搞穩定性治理。
最佳實踐是:搭建一個穩定性治理的框架,把穩定性治理手段填充進去,根據業務所處階段,選擇適合當下的穩定性治理手段,可以通過如下的表格進行管理:
一級分類 | 二級分類 | 治理手段 | 解決啥問題 | 在啥階段做 | 閉環治理方案 |
---|---|---|---|---|---|
事前 | 容量 | 常態化壓測 | 直觀瞭解服務容量,幫助評估容量夠不夠 | 成熟期 | 略 |
限流治理 | 設置qps上限,避免異常流量導致的事故,如爬蟲 | 成熟期 | 略 | ||
彈性伸縮 | 高峰期自動擴容,低峰期自動縮容,相同成本下讓系統容量更高 | 成熟期 | 略 | ||
高性能 | 超時治理 | 設置介面超時時間合理,避免下游故障導致雪崩 | 中期 | 超時治理方案 | |
慢SQL治理 | 解決慢sql引發資料庫故障,從而導致的事故 | 中期 | 略 | ||
變更管控 | 上線checklist | 通過checklist規範,降低變更引發故障的概率 | 早期 | 略 | |
灰度發佈 | 通過灰度發佈能力(AB灰度、鏈路灰度、沙箱灰度等),控制線上問題的影響範圍和影響時長 | 成熟期 | 略 | ||
無損發佈 | 通過無損發佈能力,避免請求鏈路異常斷開,引發的臟數據 | 中期 | 略 | ||
災備 | 降級治理 | 非核心依賴故障時,摘掉依賴,控制線上問題的影響範圍和影響時長 | 成熟期 | 略 | |
隔離 | 分物理隔離和邏輯隔離,比如微服務強調中間件隔離,即多個應用不要使用相同的DB、redis等,能夠減少中間件故障導致的影響面 | 早期 | 略 | ||
故障演練 | 通過故意植入故障,檢驗系統的健壯性,提前發現&解決潛在問題 | 成熟期 | 略 | ||
多機房 | 同一個應用的多個機器,分佈到不同機房,避免一個機房故障導致應用整體不可用 | 中期 | 略 | ||
大報文治理 | 避免大報文引起的系統故障 | 成熟期 | 治理方案 | ||
工程質量 | 靜態代碼掃描 | 發現&解決代碼中的潛在風險,減少帶到線上的問題數量 | 早期 | 略 | |
單測 | 增加自測環節,減少帶到線上的問題數量 | 中期 | 略 | ||
自動化測試 | 通過流水線等自動化工具,對應用進行測試,減少帶到線上的問題數量 | 中期 | 略 | ||
安全 | sql註入 | 避免sql註入的引發的線上問題 | 早期 | 略 | |
越權 | 避免越權(水平越權、垂直越權)的引發的線上問題 | 早期 | 略 | ||
反爬 | 接入反爬平臺,及時發現和反制爬蟲,避免爬蟲引發的線上問題 | 成熟期 | 略 | ||
事中 | —— | 監控告警 | 梳理監控全景圖,將誤報率和漏報率控制在合理區間 | 早期 | 略 |
故障定位 | 通過工具、平臺快速定位故障,快速發現和解決線上問題 | 中期 | 略 | ||
SOP | 指定標準操作手冊,知道大家發現和解決線上問題 | 中期 | 略 | ||
事後 | —— | casestudy | 對線上問題進行復盤,並落地改進項,持續提升團隊技術水準 | 早期 | 略 |
備註:穩定性治理框架建起來後,治理手段可以隨時增加、減少,框架的價值是給我們一個全景圖,讓我們知道該乾什麼、在乾什麼,而不是瞎乾。
根據上一章節的穩定性治理框架,接下來要做的就是針對某個治理手段,出具體的治理方案,要求具體方案能夠形成閉環,並融入到研發過程中去,比如:
-
“慢SQL治理”的落地方案
-
定義慢SQL的標準,即執行時間超過多少ms算慢SQL
-
通過監控平臺發現慢SQL
-
給研發負責人發治理工單
-
驗收治理效果
-
“超時治理”的落地方案
-
為每個介面定義合適的超時時間
-
每周巡檢一次介面,發現超時時間不合理的介面
-
修正超時時間
穩定性治理是一個長期的過程,要把穩定性的工作融入到研發過程中,一方面要有意識儘量別埋坑,比如微服務強調中間件隔離,我們就不要混用中間件了,另一方面穩定性問題要一步到位,比如治理超時時間,要有個完整規範定義超時時間,併在研發過程中對新增介面、歷史介面都配置合理,且能夠動態更新。
本文來自博客園,作者:古道輕風,轉載請註明原文鏈接:https://www.cnblogs.com/88223100/p/Stability_building_framework.html