四個步驟,教你落地穩定性保障工作

帶你聊技術發表於2023-01-11

四個步驟,教你落地穩定性保障工作

序-好記性不如爛筆頭

穩定性是個啥?
第一次接觸穩定性這個詞是在加入阿里第一年的雙十一KO會上。接觸到限流、擴容、壓測等詞彙,只覺得穩定性工作是瑣碎的、繁雜的、無流程性的、無明確衡量指標的、無從下手的。
今年,我和兩個小夥伴一起在穩定性保障工作中投入了大量的精力,我也從他們那裡學到了不少關於穩定性保障相關知識,開始對穩定性工作有了一定的理解。
穩定性工作也是有條理有步驟的,按照步驟一步步來,就能夠輕鬆將穩定性保障工作做全、做對、做好。
所謂好記性不如爛筆頭。趁機梳理記錄下來,以便後續使用時能夠信手拈來。

什麼是穩定性保障

那麼到底什麼是穩定性保障呢?
根據前人總結,穩定性保障就是保障系統的穩定,在各種不可預知的情況發生時仍然能夠持續穩定的執行和提供服務。
個人感覺穩定性保障很像一個水利工程。在應用系統中,水可以是使用者流量,也可以是資金流。而穩定性工作就是保障這些水能夠按照預定的渠道路徑流淌,保障沒有滲水、漏水、渠道垮塌的現象,或者出現這類現象也能夠及時修復將損失降到最低。

四個步驟,教你落地穩定性保障工作

穩定性保障工作做什麼

穩定性保障工作到底做什麼?自然是實現穩定性保障目標。
根據前文穩定性保障的定義可知“在各種不可預知的情況發生時仍然能夠持續穩定的執行和提供服務”就是穩定性保障工作的目標。
這個目標怎麼實現?還是一頭霧水,無從下手。那是因為這個目標太大太虛了。
遇到一個大而虛的目標,可以使用目標細化分而治之的方式。需要如下圖的紅色虛線箭頭所示的幾個步驟。
四個步驟,教你落地穩定性保障工作
首先,將目標細分為子目標,可以透過抽取目標中的關鍵字定義子目標。從“在各種不可預知的情況發生時仍然能夠持續穩定的執行和提供服務”中可提取出 不可預知的情況、發生時、持續穩定、執行、提供服務。這五個關鍵字就是穩定性保障工作的子目標。
然後,針對每個子目標進行提問,凡是自己有疑問的都羅列出來。包括但不限於對目標的理解類疑問、對目標實現的方法類疑問、對目標實現的標準類疑問。
之後,對自己所有的疑問找出答案或解決方案。就像上學期間導師給出課題,自己去理解去解決的過程。這可能需要查閱資料、現狀分析、方案選擇、最終決策、實際落地。
如此,所有的子目標都將逐一實現,最終,子目標的實現進而完成終極目標的整體實現。
綜上,上圖中最外層的淡藍色圈中的內容就是我們為了實現穩定性保障目標所需要做的工作了。初看起來很多,細看下來隱有規律,再看之下發現本質就是這幾點:什麼現象?如何發現?什麼影響?如何處理?現象、影響、處理方式都與具體異常耦合,發現靠監控告警。
總結起來就是:梳理異常情況->配置監控告警->評估影響面->預定解決方案
接下來,將從這四個步驟入手闡述穩定性保障工作具體如何落地。大框架先展示如下圖所示:
四個步驟,教你落地穩定性保障工作

梳理異常情況

那麼什麼是異常情況?異常情況很多很瑣碎啊,像RT飆高、訊息佇列阻塞、FullGC、NPE、資料異常、資料不一致、資金金額計算出錯、資料庫連線超時、網路異常、程式碼出現bug造成異常等等,這麼多梳理起來如何保證覆蓋率?
繼續使用前文的目標細化分而治之的方式,但此時目標細化無法透過拆分關鍵字實現了,此時可以透過類目細化的方式定義子目標
對異常情況進行類目細化。從上面列出的這些異常情況可進行歸類梳理,可見訊息佇列、資料庫連線、FullGC等都是中介軟體導致的異常,而程式碼bug、資料不一致、資金金額算錯這類異常屬於開發寫出的bug或者產品設計缺陷。綜上,可將中介軟體這類異常定義為基礎設施異常,bug和產品缺陷類的異常定義為業務功能異常。
再反向梳理一下,基礎設施異常包括網路、容量、連線、磁碟、快取、JVM等等中介軟體或者底層硬體設施產生的異常;這類異常日常一般不會發生,只可能發生在大而突然的流量變化時,基礎設施扛不住過大的流量導致異常。因此多發生在大促期間。
業務功能異常包括程式碼邏輯異常和資金異常。與業務功能息息相關,因此這類異常一般出現在每次業務邏輯的變更後,與日常需求相對應。可在每次業務需求開發的同時進行梳理,也可根據異常梳理結果在程式碼中預置開關和訂正工具,萬一上線後異常情況出現,就可使用預置開關和訂正工具進行止血和修復。

順便提一下,根據異常的分類,平日裡大家習慣性將穩定性保障工作分為日常穩定性保障和大促穩定性保障。

  • 日常穩定性保障主要針對業務功能異常。此類穩定性保障工作伴隨著每次業務需求開發同步進行,釋出要先於業務功能釋出。日常的業務功能變更一般不會引起基礎設施異常,因此日常穩定性保障較少涉及基礎設施的保障。

  • 大促穩定性保障主要針對基礎設施異常。因為大促會導致比日常高數十倍數百倍甚至數千倍的流量增長,此時基礎設施將面對巨大的壓力,就會出現各種異常。大促穩定性保障工作是在每次大促前需要完成的工作。


配置監控告警

監控告警分為三類,基礎設施監控告警、業務功能監控告警、資金安全監控告警。
基礎設施監控告警一般都是在應用建立之初進行配置的,涵蓋應用和所有的中介軟體、網路等。集團對基礎監控告警的覆蓋範圍有明確規定。
業務功能監控告警都是在日常業務功能開發時由開發人員配置的,用於監控特定的業務場景。
資金安全監控告警主要面向與資金相關的應用,例如下單支付。如果沒有就需要從0到1的建立,之後就隨著每次業務功能開發進行增量式設定。
大促前夕一般會對所有的監控告警進行梳理並查漏補缺。

資料流向圖

監控告警配置其實是個省略句,其完整的表達應該是:監控告警資料來源的準備、監控告警配置。
四個步驟,教你落地穩定性保障工作
監控告警的整體資料流向如上圖所示。主要透過日誌、訊息、持久化資料作為資料來源,將資料收集起來後用於監控告警的配置。
其中日誌主要用於監控大盤展示,實時反應線上真是情況;訊息主要用於實時核對的觸發媒介,觸發資金安全核對,資金安全核對透過採用旁路核對、資金一致性核對、兩兩核對等方式核對線上邏輯;持久化資料主要用於離線核對,透過兩兩核對的方式校驗資料正確性。具體核對邏輯後文詳述。
最終,監控核對都將告警資訊彙總到告警系統,觸發告警。同步到告警響應人進行處理。

配置步驟

綜上對監控告警的資料來源及其流向有了瞭解,就可以按照以下步驟配置監控告警了:
四個步驟,教你落地穩定性保障工作
值得一提的是,雖然先要有資料,才能配置監控。但是其實資料準備和監控配置這兩者應該是並行的。根據監控項的大概規劃準備監控資料,然後進行監控告警配置,有任何資料不滿足配置的情況都要返回進行資料準備步驟。
個人認為一個監控的好壞評判標準主要透過三個指標:正確性、覆蓋率、直觀性。正確性保證監控的基本功能,能夠正確的反應真實情況。沒有正確性的監控毫無存在意義。覆蓋率是衡量一個監控系統成功與否的關鍵指標,覆蓋率越高,監控系統就越能夠完美的體現系統的實際執行情況。直觀的展示監控指標有助於快速發現異常、快速定位問題。
對於告警,個人認為告警的配置最重要的是:及時性、有效性、責任制。告警出現一般都是有異常情況,可能涉及到資損或者故障,發現越及時,止血越及時,損失就越小。告警最終都是人工處理,無效的告警會浪費人力成本,因此告警配置要注意過濾噪音,保障告警的有效性,保證報出的確實是問題。至於責任制則是強調告警必須要有人響應,每條告警最好分配到人。有響應的告警才是最終有效的。

資金安全核對

資金安全核對的本質是檢查是否有資損事件的發生,做到及時報警快速止血,最終達到資損防控的目的。資金邏輯相比一般的業務邏輯存在一些共性,因此我們能夠針對這些共性思考出一些通用的資金安全核對方法和資損防控措施。
對於資金安全核對的方法論,根據前輩們的總結概括,資金安全問題主要是對資金關鍵要素的處理過程中出現異常導致的。資金關鍵要素的生命週期主要包含三個重要節點:生產、傳遞和消費。三個節點分別可能出現的錯誤為生產錯誤、漏傳錯傳、消費錯誤。針對這些錯誤,前輩們提出三大核對方法,所謂核對,都是尋找有一個正確資料作為預期,將實際情況與預期資料進行對比核對。
四個步驟,教你落地穩定性保障工作

  • 基線核對是將歷史資料作為預期進行對比核對,這種方式依賴歷史資料的正確性,投入少,實效低,可發現大的資金問題。

  • 兩兩核對將上游作為預期,進行對比核對,精準度高,時效性高,成本比較高,難以覆蓋全面。

  • 業務邏輯核對將業務專家的經驗作為預期進行核對,需要大量人力投入,對經驗的依賴度高,但是精準度高,時效性高。

面對資損防控,我們可以採用哪些具體的落地措施呢?
我的專攻資損防控的小夥伴做了很全面的總結歸納,如下圖所示,資損防控的策略包括儲存量、盤增量、控高危、盯特有。資損防控是一個長期的過程,需要時常維護,對存量布控不斷最佳化保鮮;對新增變更進行資損評估,釋出前卡點確認,保證有對應的核對規則;對於易資損場景和資料進行專項重保;對大促特有邏輯或者場景進行特別關注。
四個步驟,教你落地穩定性保障工作
資損防控,需要對全鏈路資金安全風險場景進行梳理,從失血型別、規則表達、規則型別、依賴因子等多方面分析資損場景,建立相應的失血模型。為保證快速、精確,可監聽非同步訊息來進行實時核對,同時結合特定的錯誤日誌告警,再加上小時級離線持久化資料核對兜底來保障資金安全。對於核對指令碼,可透過組織review和攻防驗證保障其正確性。
建立資損大盤,在大促高峰期值班期間安排專人盯盤,及時響應問題處理,同時對於高資損風險項預置必要的應急預案,在緊急情況發生時可以及時熔斷止血以保障資金安全。

預估影響面

影響面自然也是和異常相關的。
基礎設施的異常分多種,例如程度較輕的僅僅是短期內的負載高,嚴重的某個中介軟體(例如MetaQ)不可用、機房斷電,光纜被挖斷。其異常的嚴重程度直接決定了影響面,可能錯誤率飆高、RT飆高、訊息阻塞、FullGC頻繁,影響到系統的持續穩定性,也可能系統癱瘓不可用、網路不可用、流量跌零。不過對於這種嚴重的異常一般不會發生。機房都是多機房部署,硬體容災考慮有專門的團隊去保障。中介軟體也要專門的團隊運維保障。
穩定性保障工作對於基礎設施異常一般只考慮大促流量激增引起的容量不足、系統壓力大等問題。這類問題的原因明確,就是流量過大。直接現象就是錯誤率飆高、RT飆高、訊息阻塞、FullGC頻繁等,較嚴重的情況下會引起客訴和輿情。
業務功能異常就是錯誤,無論是邏輯異常還是資金計算錯誤,資金流轉錯誤,本質上就是產品設計有缺、開發留下的bug或者某處配置有誤。這類異常與具體的業務場景有關,小則僅影響某一個區域性小功能,大則影響核心功能。可能引起客訴和輿情,資金異常可能導致資損。

預定解決方案

前文大框架中,我們已經知道了預定的解決方案大概有限流、壓測、擴容、預案等措施,那麼這些解決方案具體如何落地呢?他們之間是否存在一定的順序?
解決方案與異常型別強相關。不同的型別有不同的解決方案。因此解決方案也分為業務功能異常的解決方案和基礎設施異常的解決方案。

業務異常的解決方案

穩定性保障對於業務異常主要是從“萬一發生了怎麼辦”這個角度出發去思考解決方案的。因此需要提前準備錦囊,以備不時之需。
業務類異常的解決方案一般分為三類,止血解決方案、臨時解決方案和長期解決方案。需要消耗的時間逐漸增多,對問題的解決程度逐漸增加。都是問題發生後的應對方案。
止血解決方案一般不需要走程式碼變更釋出,透過預案、設定、開關等實現,通常也是需要提前有所計劃,有所準備的。臨時解決方案和長期解決方案一般需要走程式碼變更釋出,耗時較長。因此遇到問題一般都先執行效率最高的止血解決方案,如果止血解決方案依舊承受較大的損失,就需要快速拿出臨時方案來解決問題,臨時方案雖然一定程度上解決了問題,但是可能存在一些小功能問題、效能問題或者優雅性方面的瑕疵。因此需要在問題得以緩解之後思考出一個穩定優雅的長期解決方案。當然,那已經是後話了,不屬於穩定性保障的工作範疇。
對於業務功能異常,在日常開發時就需要提前打算,準備好能夠多維度多程度降級的開關或者設定,留作異常發生時緊急止血使用。也就是預案。
預案需要預演進行驗證,保證預案配置和執行的正確性。
四個步驟,教你落地穩定性保障工作

預案

預案的本質是一個或者多個能夠快速改變程式碼邏輯的設定。例如開關、diamond配置或者其他工具,將這些配置跳過繁瑣的審批流程、實現快速執行就是預案,是用於大促前期關閉非核心功能、大促期間緊急問題及時止血保障主要功能而選擇斷尾某些功能的操作配置。
預案按照執行時間分為提前預案和應急預案。
提前預案是大促前期自動執行用於關閉非核心功能以保障核心功能的預案,例如日誌降級等;這類預案一般不會造成損失,風險可控,影響面是業務和消費者都可接受的。
應急預案是大促期間發現線上問題,經過大促負責人審批同意後由相關測試或者開發人員手動執行,用於及時止血以保障主要功能的預案。這類預案類似於壁虎斷尾的行為,捨棄小的損失,保留大的功能,因此一般都存在一定的損失。
預案項需要提前梳理清楚,對功能無影響但是對效能無影響的錦上添花的部分在大促期間是是可以作為提前預案降級;對於可能出現異常情況的程式碼邏輯,或者評估風險較高的邏輯都要不吝增加開關設定,實現多維度降級(業務身份維度、商品類目維度、商家維度等等),在大促前夕配置好緊急預案。
預案設定越多越好,但是預案執行須謹慎。預案越多,能夠快速應對的異常場景就越多,就越能夠快速止血,當然也要考慮維護成本。但是配置預案的時候就要全面細緻的評估清楚其執行影響,這樣到了執行的時候才能正確選擇合適大小的創可貼應對止血傷口。執行預案時須謹慎,按照大促要求走相應的流程,保證有double check。

預演

預演就是預先演練一遍。包括功能預演、活動預演、預案預演等。

  • 功能預演:提前將功能演示一遍,保證功能的正確性。注意核心功能的覆蓋率,尤其是未參加過大促的新功能。

  • 活動預演:主要面向某些大型活動進行提前預演。例如預售。

  • 預案預演:對預案進行演練測試。每一個預案在建立後都會進行一次預案預演,以保證預案執行結果符合預期。


基礎設施異常的解決方案

穩定性保障對於基礎設施異常主要是從“如何才能不發生”這個角度出發去思考解決方案的。因此需要提前修煉內功,增強自身實力。
對於基礎設施異常,一旦發生,難以快速止血和修復。因此一般都是在大促前夕就要做足穩定性保障工作保證大促時不發生或者少發生這類異常,可透過壓測、預演提前發現異常,提前提出解決方案進行修復處理。
如前文所述,對於基礎設施異常,穩定性保障工作僅考慮流量過大導致的異常。因此這類異常的原因明確就是流量過大。其解決方案也就明確是解決流量問題,分為對外解決方案和對內解決方案。對外限流拒絕過多流量對自身進行保護,但限流需要基於容量預估,有考量有依據的設定。對內擴容增強自身實力,並提前預熱做好應對準備。
內外解決方案透過壓測相互協調配合,最終達到一種權衡利弊後的和諧。
四個步驟,教你落地穩定性保障工作
綜上,先要進行容量預估,預估外部流量峰值,再根據預估容量進行限流設定,然後進行壓測,評估內部容量是否能夠支撐預估容量,如果無法支撐,就要考慮擴容,擴容後根據機器數量進行限流調整,然後再次壓測,壓測後能夠支撐預估容量甚至遊刃有餘時可以考慮再次調整限流,承載更多的流量。最後可以考慮在大促前進行快取預熱防止流量峰值擊穿快取。

容量預估

容量評估要做的事情總結起來就是三件:

  • 1、對上游:詢問預估流量,即他們要求我們的保障值。上游需要呼叫我們的服務,因此我們提供的服務量級需要滿足他們的訴求。簡言之,我們的水渠需要能夠容納得住從他們那裡流下來的水流量。

  • 2、對自身:梳理自身上下游鏈路,基於自身預估,根據上游訴求,預估對下游的訴求。

  • 3、對下游:提供自己的預估容量,要求下游提供足夠的容量。

自身容量如何預估呢?一般是透過以下幾個方法進行:

  • 1、梳理業務變化對流量影響:業務邏輯每年都在變化,進而對流量有所影響。因此要梳理去年同一大促結束到今年大促之前這段時間內的業務變化,預估其對流量的影響量。

  • 2、參考往年同一大促容量值:梳理往年同一大促的流量、峰值發生時間、整體流量走勢;參考預估,沒有影響流量的業務變化的情況下(理想情況),基本可以直接用來作為預估值。

  • 3、參考同年之前的大促容量值:梳理同年前一次大促的流量參考預估。對比往年兩次大促的流量比例來預估,例如,如果去年618與雙11的的流量比是1:2,那麼可以將今年618的容量乘以2的值來作為今年雙11的容量預估值。

  • 4、結合上游訴求:收集到所有上游的訴求保障值,總結歸納。再對比自身預估容量。一般是兩者取大。但是如果差異很大,就需要再認真核對,可能有預估錯誤或者遺漏。

四個步驟,教你落地穩定性保障工作

對下游的訴求保障值如何預估呢?

  • 1、根據程式碼邏輯總結容量公式:程式碼鏈路梳理,彙總出對下游每個介面的呼叫場景和次數,最終得到下游每個介面的總呼叫量的公式,入參是自身容量,出參就是下游介面的容量。不過這個方法有個缺點就是一旦呼叫鏈路發生變化就需要及時更新,有一定的維護成本。優點就是精確度高。

  • 2、參考歷年容量:這個方式同上文自身容量的預估方式。可參考往年大促呼叫量預估今年容量。

限流

限流類似於水渠源頭的閘門,這個閘門開的大小直接決定了水渠中的水流量。將閘門開啟到一定程度,而非完全開啟,保障水渠不至於被沖垮的行為就是限流。
無論有沒有擴容,無論系統是遊刃有餘還是苦苦支撐,都需要對系統進行限流。限流是系統的門衛,超出的容量可以被攔截在外。
我們一般都使用單機限流,即設定單臺機器最大可接受的QPS,超過則觸發限流,限流可以直接拒絕,即快速失敗,也可以排隊等待。單機限流可以進行呼叫來源應用維度的限流,可以對所有上游應用一概而論(流控應用設定為default),也可以因人而異保障主要業務(針對核心的應用限流設定較大,非核心的應用限流設定較小)。
也可以考慮叢集限流,對整個叢集進行限流。

壓測

所謂壓測,就是構造資料流量透過幾臺壓力機模擬使用者持續併發請求系統介面,測試系統的效能和承受能力的過程。
集團的壓測分為單鏈路壓測和全鏈路壓測。所謂單鏈路壓測,即自己的應用服務入口作為壓測入口進行觸發壓測,主要面對的僅限於單個應用,涉及應用少,涉及人員少。全鏈路壓測則從使用者實際操作入口作為壓測入口,這個操作涉及到的所有應用服務全部參與壓測,是一個跨部門跨應用的過程,每次全鏈路壓測,涉及到鏈路上所有團隊的協調參與共同努力。
全鏈路壓測更能反應線上真是情況。條件允許的情況下都選擇全鏈路壓測。
集團的壓測都會提前構造影子鏈路,即真實鏈路的影子,和真實鏈路一模一樣,卻又不會對真實鏈路產生影響。庫表也是使用影子表,將壓測的持久化資料與真實持久化資料分開。
壓測是一個複雜的過程,需要專業的壓測團隊的同學支撐。對於一個從未參加過壓測的應用而言,要做的工作簡要概括如下:
四個步驟,教你落地穩定性保障工作

  • 1、應用適配改造:要走通壓測鏈路,涉及改動較多,包括應用系統改造、nginx升級、中介軟體改造、快取端升級、DB端升級等等。

  • 2、構造壓測資料:壓測資料構造需要根據具體的業務。例如價保的壓測,需要構造的壓測資料是處於價保有效期內的訂單。如果要壓到申請鏈路,還要構造優惠製造差價。

  • 3、建立壓測模型:所謂壓測模型是指壓測資料的分佈情況,壓測模型要能夠反應線上真實流量佔比。要覆蓋到所有鏈路,不同業務的流量佔比等同線上真實情況,中心機房和單元機房的流量比例也要按照線上比例分配。

  • 4、進行壓測:壓測分為單鏈路壓測和全鏈路壓測,單鏈路壓測是指僅僅對自己關注的系統進行壓測;全鏈路壓測是從使用者發起請求開始到整個業務邏輯結束的全部鏈路壓測。壓測入口也分為http介面壓測和端上介面壓測,具體根據系統情況而定。

  • 5、觀測與總結:在壓測的過程中,要時刻盯盤,觀測系統水位。壓測後總結梳理出壓測報告。

壓測一般不是一次就能夠完成的,可能因為各種原因導致壓測結果不理想,因此要多次壓測,每次根據壓測問題進行修復後再次壓測,直到壓測結果符合預期為止。
上圖中只繪製了壓測適配原因導致的重新壓測,如前文所示擴容和限流後也要進行壓測。

擴容

擴容,就是暴力增加機器。所以也要考慮成本。
如果壓測的結果,系統無法達到上游訴求,為了保證業務的順利進行。就需要擴容,並再次壓測,直到系統能夠保障目標容量。
如果壓測的結果皆大歡喜,滿足了上游訴求,那麼就不需要擴容了。

預熱

預熱可簡單的理解為參賽前的熱身。讓容器、快取、資料庫等都準備好迎接大促的流量峰值。
四個步驟,教你落地穩定性保障工作
預熱分為快取預熱和啟動預熱。快取預熱屬於大促穩定性保障工作,但是啟動預熱屬於一種日常的效能最佳化。
集團每年大促的商品預熱是被人所熟知的。就是將熱點商品提前載入進快取中,避免大促期間快取擊穿,流量直接打掛db的情況。這就是快取預熱。多用於大量依賴快取的應用。
啟動預熱一般是處理服務剛啟動時服務RT較大甚至超時的問題,處理方式是在啟動時透過構造引數,模擬真實請求的方式把程式碼跑熱後再對外提供服務。

總結

穩定性保障工作從時間上來說,包括日常業務需求開發時的監控告警配置和開關預留,大促前夕的容量預估、壓測、限流、擴容和預熱,其實還有一部分,上文未及提及,那便是大促值班。
建議在值班前寫一個值班手冊,將可能出現的問題,解決方案,需要使用到的工具連結全部羅列清楚,避免值班時手忙腳亂找資料找工具。還有必要的許可權申請在值班前申請好。
在大促期間,嚴陣以待,這個時候需要做到兩動,主動關注監控大盤,注意流量變化,監控基礎設施指標;被動關注告警,一旦被告警提醒就是有異常情況了,要立刻投入定位解決。
最後,穩定性保障工作是沒有盡頭的,其重要性不言而喻,但是也要在業務功能與穩定性之間做好權衡,如果穩定性核對的呼叫流量都超過了業務流量,那麼穩定性工作就有點過了,從機器成本、人力成本上都沒有這個必要。
本文整理了自己對穩定性保障的認識和理解,可能存在理解有誤或者認識不足的情況歡迎指正,也期待更多的學習逐漸修正和完善自己的穩定性相關知識。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/70024922/viewspace-2931745/,如需轉載,請註明出處,否則將追究法律責任。

相關文章