農林漁牧網

您現在的位置是:首頁 > 農業

又一宕機事故!都怪當初沒做好故障演練系統……

2022-12-03由 dbaplus社群 發表于 農業

監測站裝置宕機重啟的原理是什麼

本文根據劉志志

本文根據劉志志

又一宕機事故!都怪當初沒做好故障演練系統……

老師在〖deeplus直播:逆襲生產力擔當,雲原生時代的運維新歸宿〗線上分享演講內容整理而成。

去哪兒網 系統運維工程師

致力於提升工程師的效率和保證交付過程的質量,在私有云搭建及測試領域都有深入研究,目前主要從事Devops平臺以及混沌工程相關係統的開發和維護。

大家好,我是來自去哪兒網的劉志志,19年加入去哪兒網,主要參與CI/CD平臺建設,負責故障演練平臺的開發。今天的分享主要分為以下三個部分:

又一宕機事故!都怪當初沒做好故障演練系統……

老師在〖deeplus直播:逆襲生產力擔當,雲原生時代的運維新歸宿〗線上分享演講內容整理而成。

又一宕機事故!都怪當初沒做好故障演練系統……

如圖所示,左邊是近期發生的一件影響較大的事故:

Facebook服務宕機。

持續時長約7小時,造成了次日超過60億美金的市值下跌,損失數額巨大。

右邊所展示的則是我們公司中某個業務線的服務呼叫關係。

可以看到,整個鏈路非常複雜,如果其中某個鏈路出現問題,就有可能導致上下游發生故障,甚至造成整個業務癱瘓。

而現實生產過程中存在著各種各樣的故障,我們有什麼方案可以應對這些故障、做好應急預案,以增強我們對故障抵禦的信心呢?

答案是演習。

很多行業都會有演習,包括軍事演習、消防演習等。而軟體開發領域也有一個類似的實踐,即故障演練。故障演練可以透過模擬真實故障,驗證系統弱點,同時幫助我們完善故障應急預案和處理體系。

我們公司曾經因為微服務太過複雜而導致故障頻發,在此之前,公司內部並沒有統一的故障演練工具。19年攜程曾經出現過一次宕機事故,當時正值五一促銷前夕,造成了較大的負面影響。因為我們跟攜程的子公司關係,這件事也給我們敲醒了警鐘。從那之後,我們便開始著手做故障演練。

劉志志

又一宕機事故!都怪當初沒做好故障演練系統……

我們的故障演練系統主要經歷了三個演進階段:

第一個階段是關機演練。這個時候正處於系統初建時期,以資源型演練為主。將內部的IM接、許可權接進來,同時接入監控告警。

第二個階段是強弱依賴演練。這個階段主要做的事情是應用間依賴資訊的收集。在這個階段我們做了依賴標記的入口,並接入了線上迴歸巡檢。

第三個階段是容器化的支援。從去年底到今年,應用開始往容器上遷移,配套工具也因此需要進行升級,所以我們也做了容器化的支援。

一、背景&價值

又一宕機事故!都怪當初沒做好故障演練系統……

首先來介紹一下關機演練。

因為當時還沒有系統,所以需要先進行選型。

圖片中展示的是我們當時的備選系統,分別是:

Netflix公司的ChAP、阿里巴巴的Chaosblade和PingCAP的Chaos Mesh。

Netflix它是透過釋出系統擴容來建立實驗環境的,可以將對生產環境影響降到最低,但因為它並沒有開源,所以也沒法考慮,我們在選型時主要考慮Chaosblade跟Chaos Mesh。跟Chaos Mesh相比, Chaosblade支援虛擬機器和K8s上的演練,場景比Chaos Mesh更為豐富。它支援多語言應用服務,比如Java、Golang、C++等。而Chaos Mesh它的整體性比較好,既有故障注入也有控制面,Chaosblade當時只有Agent。

又一宕機事故!都怪當初沒做好故障演練系統……

二者各有優劣,而我們公司當時的狀況是:

底層的資源基本上都是虛擬機器,故障注入也是以虛擬機器場景為主,公司內部基本上百分之八九十的後端服務都是Java。

所以相對來說,Chaosblade更契合我們當時的場景。

我們當時選擇用它的Agent,加上自研控制端來實現。

這是Chaosblade的簡單介紹。

又一宕機事故!都怪當初沒做好故障演練系統……

官網上對它的介紹是:它是一個簡單易用並且強大的混沌工程工具,今年加入了CNCF Sandbox 專案。

主要分為三個部分:

Chaosblade。命令列工具,包含一些執行器,可以實現Go、Java、C++等幾種語言和Linux作業系統以及容器的故障注入。

Chaosblade-box。今年年初開源的控制面。

Chaosblade-operator。可以在K8s上使用。

上圖的右部分羅列了它的一些故障注入能力,從基礎資源到應用服務到雲原生基本上都有包含,能力較為全面。同時它還跟雲平臺有較好的結合。我們這邊主要使用了它的Chaosblade跟operator,而Chaosblade主要是應用在 OS層和JVM。

選型和分析結束之後,接下來是關機演練。

首先是我們的演練目標:

流量正常切換

核心服務容量保障

弱依賴服務不影響主流程

中介軟體&儲存高可用

而要想實現這些目標,大概需要演練平臺的能力能達到:同一機房某業務線所有服務節點全部關機(單次1k節點)的水平。

在正式開始關機演練前,我們在設計階段需要考慮以下幾點:

機房聚合資訊查詢,方面應用改造

自動拉群,進度周知

虛擬機器關機,實體機kill程序

接入告警,告警事件關聯推送

虛擬機器開機後關聯服務自動恢復

這是關機故障的實際流程圖:

又一宕機事故!都怪當初沒做好故障演練系統……

左邊是虛擬機器。

虛擬機器關機是 Ops封裝提供關機介面,由演練平臺發起關機,Ops平臺會將結果多次回撥給我們,回調了之後,我們這邊再做一次ping,相當於二次確認,對於超時的要做單個的重試。

然後是開機。

開機是批次開機,在收到了成功訊息之後,呼叫我們的自助運維平臺去將服務拉起來,然後做上線。

而實體機使用的是Chaosblade的Agent,和虛擬機器相比,它的不同之處在於,它在kill程序之前需要先裝上Agent。我們公司內部使用的運維工具是 Saltstack,在關機階段,我們會把Agent安裝上,然後在機器上啟動Chaosblade的一個HTTP服務。Agent安裝完了之後會呼叫kill策略結束服務對應的程序。開機的時候就是正常地把服務拉起來,但最後會解除安裝Chaosblade。

這部分我總結了兩點經驗:

非同步任務,合理超時,開關機如果時間太久,需要人工進行兜底。

Chaosblade的安裝包大概100M,如果機器的網路資源比較緊張就需要考慮一下限速。

下面介紹一下使用者的演練流程:

又一宕機事故!都怪當初沒做好故障演練系統……

整體流程跟學校裡的考試流程有些類似:

考前複習 — 學生做卷子練習 — 學校統考。

而對於單個服務負責人來說,他們也需要經歷這幾個步驟:

梳理 — 改造 — 模擬驗證。

二、故障演練系統演進

在做統一的關機演練之前,我們會列出checklist,每個服務都要去自檢:本身是不是做了多機房?服務依賴的中介軟體、儲存等其他的服務是不是也做了多機房?還要對容量進行評估,特別是核心系統。同時還要做擴容的測試,防止在真正宕機時要做應急擴容的情況發生。

1、關機演練

在改造階段,我們會根據 checklist發現的問題進行針對性改造。

梳理

透過故障演練系統對單個機房模擬宕機。

每個業務線一般都有專門的演練負責人,他們負責組織、進行演練以及覆盤的相關事宜。

改造

提前規劃好時間和演練的應用範圍以及機房資訊,將一些不能夠參加演練的應用排除,並根據這些資訊生成演練,進行周知。

驗證

一般較大規模的演練會選在低峰時段進行,由負責人進行演練流程的控制:開啟 — 結束 — 恢復。相關的業務負責人會去關注業務情況,如果中間發生了業務抖動等意料之外的情況,就需要去溝通是否是要終止演練。

組織

演練完成之後還需要進行復盤,對演練過程中發現的問題進行總結敘記錄,同時針對這些問題制定改進計劃以及下次的驗證計劃。

最開始的演練投入的人數比較多,一開始有幾十個人參與,但是到後面做驗證性的時候基本上一兩個人就可以做上千個節點的演練。

演練

什麼是強弱依賴?舉個例子,服務A依賴服務B,二者之間存在依賴關係。當服務B出問題時,如果服務A的核心流程正常,那麼它們之間的關係是弱依賴;如果核心流程出現問題,那麼它們之間的關係就是強依賴。

下面是強弱依賴演練的背景:

覆盤

依賴關係導致的蝴蝶效應。

弱依賴超時是否合理,熔斷是否符合預期?

異常是否被處理等。

強依賴太多,能否降級為弱依賴?

2、強弱依賴演練

每個業務線或者每個應用負責的相關人員,他們都會做依賴的梳理,但沒有統一的依賴資訊收集管理工具,依賴查詢和梳理很耗時。強弱依賴資訊沒有統一的資料來源。

又一宕機事故!都怪當初沒做好故障演練系統……

上圖展示了一個服務依賴關係。

我們公司主要的技術棧其實比較收斂, DB一般都是Redis和MySQL ,服務訪問一般是HTTP、dubbo。

所以依賴關係的收集,主要也是基於這4種類型。

這裡簡單介紹一下服務上下游的概念。比如說服務A依賴服務B的一個介面,那麼服務A就是服務B的上游。我們在做故障注入時,一般是注入在服務A上,也就是在HTTP client或者 dubbo consumer做故障注入。故障的型別一般分為異常和延遲,如果正常的是50毫秒,那我們可以給它延遲100毫秒。

微服務穩定性治理

又一宕機事故!都怪當初沒做好故障演練系統……

依賴關係收集的主要來源有兩種:

一種是日誌,即HTTP的access。log檔案;

另外一種是服務的註冊資訊,目前我們是用ZK 做註冊中心。

我們把這些元資料彙集到一個分析聚合的服務中,它會每天更新七日內的資料,並把這些資料聚合之後生成依賴關係存到 DB裡面。

依賴關係主要包括流量和依賴方向,強弱資訊需要使用者進行標記。我們在這個演練平臺上提供了一個模組,可以實現對強弱依賴關係的標記,同時還能為其他平臺提供依賴資訊查詢。

透過日誌跟註冊資訊來取依賴關係各有各的優劣,日誌的處理量比較大,而註冊資訊可能會存在過期資料。

依賴資料統一收集管理

對於一次故障演練中需要同時注入較多故障的情況,我們做了一個編排的功能。

又一宕機事故!都怪當初沒做好故障演練系統……

強弱依賴主要依賴於 Java的 Agent。

故障注入的整個流程主要分為三步:

第一步,安裝Chaosblade,attach Java程序。

第二步,開始進行故障注入。

第三步,服務恢復,同時解除安裝attach。

在第二步,進行故障注入時,如果是多個故障的話,我們就需要有一些編排策略。比如,當我們需要將5個故障注入到3個Java服務中時,一共有三種注入方式:

一種是並行,一次把所有的故障都注入到機器上面。這種情況一般是用於驗證弱依賴,而且對於結果比較有信心。如果只是去驗證的話,一次把故障都注入進去會比較快。

另外一種是序列,機器之間注入故障是並行的,但是每一個機器上服務生效是序列的。這樣一來,每個機器上面同一時間只有一個故障,比較容易進行問題排查。

我們還提供了一個手動的流程控制,你可以根據自己的需要去選擇:什麼時候開始哪些機器上的哪些故障。

透過這三種方式,基本上可以滿足大部分故障注入的需求。

1)依賴關係收集

又一宕機事故!都怪當初沒做好故障演練系統……

使用者使用流程一般是閉環的形式。

我們把依賴關係收集好之後,使用者會進行強弱標記。

標記之後需要進行強弱依賴演練來驗證判斷:

該服務是否是預想中的強依賴或者弱依賴。

演練完成之後需要對問題進行分析修復。

故障演練平臺的使用流程跟關機演練有些類似,都是要準備、演練進行、恢復、覆盤:

2)故障注入編排

制定演練目標

選擇APP code

選擇機器資源

選擇演練策略

生成演練計劃

周知相關人員

3)使用者使用流程

Agent裝載

故障注入

用流量驗證故障是否生效

流量來源主要分為兩類:真實流量和模擬流量。我們可以透過自動化測試、人工case,也可以用流量copy,如果在線上進行演練就用線上真實的流量。同時,在演練時要做觀察日誌跟監控,如果影響了線上服務就需要及時終止。

① 演練準備

演練的恢復包括三種,一種是人工恢復,另一種是超時自動恢復,還有一種異常情就是人工觸發恢復。如果發生核心告警就會觸發這個應用,相當於演練的熔斷,這也會自動觸發恢復。恢復之後我們需要把Agent解除安裝掉。

② 演練進行

演練結束之後,我們需要把流水記錄下來,進行問題總結,做好改進規劃,同時商討下次演練時間。

③ 演練恢復

又一宕機事故!都怪當初沒做好故障演練系統……

接下來簡單介紹一下強弱依賴演練遇到的問題,主要問題都集中在Chaosblade的Java Agent上

④演練覆盤

這個Agent提供了一些開源元件的外掛,比如 Java、Mysql、httpclient、dubbo等,但有很多公司的中介軟體都是自研的,包括一些開源的元件,那這一部分它就沒法支援,可能需要自己再去按照規範進行開發。

我們在把一些開源的元件的外掛開發完成之後也提交給了官方,同時,我們自己也開發了一些功能,一個是呼叫點支援, 在程式內部的整個呼叫鏈路上,透過呼叫函式簽名在呼叫鏈路上進行匹配,做故障注入。也開發了基於Tracing 的context的匹配, 很多公司內部都有一個類似Skywalking的Tracing工具,Trace中可以攜帶一些資訊,可以根據這些資訊去做一些流量的篩選,這樣話整個的故障注入的條件會更精細。

4)問題&解決思路

我們當時在測試的時候發現httpclient的沒有完整支援delay場景,特別是非同步的。這一點我們已經把它實現了,也已經提交到了官方。

① 外掛不足

這一類問題不太好查。因為公司的介面自動化測試,有部分他用的是阿里開源的jvm-sandbox-repeator ,這個Agent跟Chaosblade Agent都是用jvm-sandbox作為底層,它們之間存在有名稱空間衝突,導致不能同時attach成功。跟內部的tracing agent也有衝突,導致故障策略無法生效。

面對這樣的情況,我們需要使用不同的名稱空間。解決方案就是用3。0以上的jvm-sandbox,在啟動的時候指定不同的名稱空間。

還有一個問題,如果公司內部有自己研發的Java Agent,比如skywalking是全鏈路壓測的這種Agent。如果基於ByteBuddy 開發,且兩個一起使用,就有可能導致Chaosblade的Agent切不到。因為這個Agent它的主要原理就是做切面增強。故障是注入進去了,但沒有生效。這是開源社群的一個issue (https://github。com/alibaba/arthas/issues/1141),但是原理跟解決方案都是類似的,如果大家遇到這個情況可以參考一下。

又一宕機事故!都怪當初沒做好故障演練系統……

還有一個問題:

在java agent attach的時候,由於需要動態做位元組碼增強,導致cpu和load都會瞬時飆。

在後續的策略下發時依舊是平穩的。

對於這個問題,解決思路是:在attach之前先做流量摘除,開始之後再把流量切入進去。因為在真正的故障策略下發時,對 CPU、Load的影響很小。

之前我們遇到過一次演練完成了,而且 Agent也解除安裝了,但是過了一段時間卻莫名掛掉的情況,至今也沒有找到原因。所以如果為了保險起見,演練完成之後,我們可以做一次服務重啟。

② 功能缺失

又一宕機事故!都怪當初沒做好故障演練系統……

如圖所示,在進行容器化支援故障注入改造方案時,我們比對了三種不同的方式,對它們的優劣勢進行分析,最後選擇了一種折中的方案。

在Chaosblade-operator上就是增加了幾個簡單的功能,包括 Agent的安裝、解除安裝,還有 Java程序的attach。策略下發用的還是原來的方式,在POD上起一個埠,透過 HTTP來進行互動。這樣一來,只需要把以前的Salt部分用operator來代替,後面的整個互動流程還是跟原來一樣,改造成本會相對較小。

我們的改造主要是實現了關機以及Java部分的故障。但是因為在POD上做網路實驗需要的許可權比較大,安全組那邊一直沒有同意,所以我們目前還沒有支援。

又一宕機事故!都怪當初沒做好故障演練系統……

這個是整個的一個架構圖,從上到下有4層。

第一層資訊來源,我們這邊是portal,就是一個應用管理平臺,主要包含應用的資訊、應用畫像等;

另外一個是依賴資訊平臺,也就是一些元資料的提供方。

接下來是故障演練系統,主要負責故障的演練編排。再往下是一些執行通道,包括Salt、Ops提供的API、Chaosblade-operator等,故障的真正注入主要是透過 HTTP介面來執行的。

下面是幾種不同的資源。右邊是提供一些通用能力的服務方,包括監控平臺、線上巡檢、許可權系統以及IM。

③ Agent衝突

5) 容器化支援故障注入改造方案

又一宕機事故!都怪當初沒做好故障演練系統……

圖中列舉了部分透過故障演練發現的風險型別,包括依賴處理不當、超時配置不合理、報警不合理等。

右邊則是我們達成的收益彙總。

三、收益&規劃

又一宕機事故!都怪當初沒做好故障演練系統……

故障演練是混沌工程的工程實踐。

簡單地來說,故障演練是混沌工程的一部分,但是它的能力相對更加底層。

故障演練更多是以測試驗證為主,但混沌工程它是透過實驗去發現系統問題;混沌工程更強調在線上做隨機化演練,而故障演練雖然也有在線上,但更多的還是先從測試環境驗證開始;混沌工程更多強調形成文化,跟Devops流程結合,故障演練目前還是以定期組織為主。

1、故障演練收益

接下來分享一下我們近期的規劃,主要包括4個方向:

2、故障演練和混沌工程

結合自動化介面測試平臺,透過基準環境和故障環境請求結果對比,結合策略命中資訊,強弱關係預判輔助使用者決策。

3、近期規劃

基於故障注入能力以及強弱依賴關係,加上tracing資訊,針對訪問鏈路上的應用進行自動計算爆炸半徑並生成自動化演練。

1)強制依賴自動標記

新功能的新增以及Bug修復已經回饋給開源版本,我們組已經有2位Chaosblade的Commitor,並且和Chaosblade社群有過深度交流,保持合作關係。

2)線上自動化隨機演練

增加可觀測性,減少問題排查時間;

演練引數固化,減少使用者準備操作。

以上就是我分享的全部內容,大家如果有什麼想法,歡迎在評論區提出~

3)參與開源共建

4)使用體驗

>>>>

>

這部分文章中有提到,這部分的資訊主要有兩個來源,一個是日誌,另外一個是服務的註冊中心以及DB的元資訊。但透過這幾個途徑只能獲得服務間的依賴關係,強弱目前還是依賴人工去做標記。

>

>

我們的演練目前既可以支援測試環境,也能夠支援模擬環境和線上環境。現在的業務也是按照一定的順序,先從測試環境開始驗證,然後到模擬,然後再到線上。而注入的流量也是如此,比如一開始是人工觸發的流量,後面就是用線上複製流量,再後面就用真實流量。都是需要循序漸進來做的。

>

Q&A

我們對Chaosblade的Java Agent做了一個開發,根據Trace當中的資訊來做流量匹配。因為我們這邊C端來的流量都會有一個標識,透過這個標識我們可以知道:它是從哪一個外網入口進來的。所以,透過Trace中的資訊做匹配,就相當於做了一個流量篩選,這樣的話就能實現精準注入。

Q1:服務依賴的故障會對業務影響很大,怎麼獲取服務質量的強弱關係圖?

A1:

我們現在主要還是依賴於監控告警和一個基於異常檢測的平臺。在注入故障之後,在這兩個平臺如果產生了故障資訊,就可以認為它不正常。我們針對故障演練做了一個分組,相當於設定了一些特殊關注的監控指標。透過這兩個平臺的事件,我們來判定它是不是我們看穩態,目前是這樣。

Q2:混沌工程直接上生產太過冒險,有沒有比較溫和的從線下走到生產的方式?

A2:

我認為應該先從無狀態應用入手。因為我們現在做的演練基本上還是以無狀態應用為主,無狀態應用它會更簡單一些,你可以把整個流程串起來,同時積累一些經驗。有狀態服務其實我們這邊做的比較少,像中介軟體或者是DB這些團隊,他們其實並沒有用我們的演練平臺,而是主要依賴於自己的一些測試手段來保證高可用。

Q3:怎麼實現全鏈路精準故障注入?

A3:

監控它只是一部分,像監控、日誌和Tracing等,而可觀測性包括的範圍更廣。

Q4:在故障注入後,要如何判定系統的穩態是否被改變,怎麼定義穩態?採用什麼手段判定?

A4:

混沌工程的實現需要從上到下的支援和配合,如果只是想自己或者用一個小團隊來做的話,可能會非常難實現。但比如說Chaosblade的Agent本身能力比較強,其實你只需要用它一部分功能做一些簡單的自動化,也可以實現故障注入的測試驗證。

想了解更多精彩內容,快來關注dbaplus社群