當前位置:
首頁 > 科技 > 依賴治理、灰度發布、故障演練,阿里電商故障演練系統的設計與實戰經驗

依賴治理、灰度發布、故障演練,阿里電商故障演練系統的設計與實戰經驗

作者|中亭

編輯|小智

2016 年,阿里巴巴研發了故障演練系統,把故障以場景化的方式沉澱到系統中,在線上主動回放故障,驗證監控報警、限流降級、故障遷移、容災策略、故障處理的有效性。本文將探討經典的故障類型,剖析故障成因,提出解決方案,介紹故障演練系統的設計和演進,提出故障演練的原則和經驗。

註:本文整理自阿里技術專家中亭在 QCon 北京 2017 上的演講,由阿里技術公眾號授權轉載。

寫在前面

本文分享的內容主要還是圍繞故障治理有關。眾所周知,故障治理本身就是一個比較大的話題,幾乎涉及到運維、研發、故障運行管理的全部崗位,奇葩一點的故障還可能涉及到運營和產品經理。聊到故障的苦與淚,相信 45 分鐘絕對連開頭都沒講完。今天的分享,主要還是回歸故障發生的本質,故障原因角度切入。看是否有一些方法論和通用性的手段可以沉澱出來。希望可以對大家有所幫助。

首先介紹一下我自己,姓名周洋,花名中亭。2011 年加入阿里接觸穩定性技術領域,開始做一些穩定性產品的研發,同時也會承擔一些架構演進的推進工作,比如 HTTPS 改造,電商交易鏈路升配等。2015 年開始搞雙 11 大促,做為共享事業部的大促負責人,保障了雙 11 的穩定。也獲得雙 11 老 A 也就是雙 11 特種兵的稱號。

共享事業部對於在座各位可能比較陌生。如果我換一個說法,商品、交易、會員、優惠、評價、中間件,大家應該就都知道了,這是雙 11 當天最具挑戰的鏈條之一。右邊是中間件核心作戰室成員,在過了雙 11 業務高峰後的一張合影。2016 年至今,工作的重點在常態穩定性的確定性方面,今天的分享也是主要圍繞這部分內容。

分布式系統常見依賴故障治理及技術演進

首先拋一個問題,什麼情況下你會認為淘寶網掛了? 我相信關注這個問題的人很多,不過能給出確切答案的人並不多。因為這個看似簡單的問題,真要回答起來好像也不是那麼容易。今天的分享,我先試著給大家回答一下這個問題。

讓我們從一張「簡單」的頁面說起。這張頁面叫做商品詳情頁,對於大部分人來講,這張頁面是他們在淘寶完成一筆訂單的第一步。而商品詳情頁的使命就是把商品的信息沒有保留的展示給大家,引起大家的興趣,引導大家完成購買或是收藏。從信息展示的角度來講,商品詳情頁確實是一張非常簡單的頁面。

我們再來看一下商品詳情頁應用的後台架構。商品詳情頁是阿里最早實現靜態化應用之一。那些與瀏覽者無關信息,比如商品標題、圖片信息、銷售屬性組合等信息均直接進入緩存,其他和用戶相關的,如優惠、庫存、物流、服務等動態信息則通過非同步調用方式填充至靜態化後的頁面框架內。為了在一張頁面展示足夠多可供決策信息,撩起用戶的購買慾望,詳情後台必須去依賴非常多的服務應用,聚合足夠多的信息。少則幾十,多則成百。從這個角度來講,商品詳情頁面又是阿里依賴最複雜的應用之一。

互聯網業務的一個主要特點是,業務迭代非常快,每天有新需求,每周都有新發布,每年都有大重構,每一次變化都有可能導致狀況的發生。越是貼近用戶的系統,受下游服務影響越大。那麼我們不僅好奇,對於詳情這個阿里最複雜的應用,下游發生一些狀況時,系統會變成怎樣?我們通過兩個實驗來觀察一下:

實驗一:假設後端的優惠、庫存、物流發生故障,我們來觀察一下商品詳情頁的表現。

乍一看,好像沒什麼問題。只是覺得頁面清爽了一些。或許在這個信息過暴的時代,看著這麼清新脫俗的頁面,還有一點點暗爽。

在現場做了兩個調查,觀察大家對實驗一的反映。調查 1 是請認為詳情頁故障了的同學請舉手。結果是現場沒有人舉手(也可能是現場氛圍還比較冷);調查 2 是請大家來找茬,前後兩個詳情頁有多少處不同?這次有一個妹子說出了正確的答案(同時也向妹子贈送了電子工業出版社出版的講述阿里雙 11 技術演進的《盡在雙 11》書籍)。

沒有對比就沒有傷害,一共有 6 處不同。從功能角度,這鐵定是一個故障頁面。不過從用戶體驗和業務角度講,少了這些信息也不影響商品購買,不影響核心用戶體驗。好像又是沒故障?有點糾結,對吧? 您先糾結一會兒,我們來進行第二個實驗。

實驗二:當商品詳情的"商品"出了問題,商品詳情會怎樣?

詳情還是那個詳情,只不過是商品詳情變成了錯誤詳情。第一張頁面:很抱歉,你查看的商品找不到了。有可能是你訪問的方式不對,比如 URL 上面少了一些參數,也可能是後台真的出問題,對於用戶還算是比較溫柔的一種方式。第二張頁面:很可能就是網站真的出問題了。比較可能的原因是後台沒有合理的處理超時導致前端異常。不過說實話,這個頁面我也非常少的見到。如果真的出現了,那基本就是一次非常嚴重的事故。

通過上面的兩個實驗,相信大家應該對於我們今天要介紹的一個概念"強弱依賴"有一些模糊的感覺了。 從感性的角度來講,就是當下游依賴服務出現問題時,當前系統會受到一些影響,讓用戶有感覺的是強依賴,沒感覺的是弱依賴。

不過這種定義不夠嚴謹,因為總不能說沒有用戶訪問時,就不算故障吧。所以也需要從理性角度定義一下:首先應該發生狀況,其次應該是核心業務,最後是否帶來損失。不影響核心業務流程,不影響系統可用性的依賴都可以叫做弱依賴,反之就是強依賴。

終於解釋清楚什麼是強弱依賴,那麼做好強弱依賴治理到底有什麼意義?拋開依賴模型來看強弱,意義不大。嚴謹的依賴模型應該包括關係、流量、強弱三個組成部分。

依賴關係定義依賴的方向,我依賴誰,誰依賴我。流量定義著每個應用、服務、方法調用的次數,強弱則定義著依賴的鬆緊程度。依賴治理就是通過科學的手段持續穩定地拿到關係、流量、強弱的數據。強弱依賴主要可以被應用到下面的場景:

系統改造驗收:對於分布式系統,至少應該做到運行態中不會因為我依賴的系統出現故障,而引起當前應用出現可用性的問題,比如進程掛掉,頻繁 FullGC,負載飆高等,何時何地都具備快速止血的能力。

限流降級參考:對於弱依賴,一般都要配置限流或是自動降級策略,比起通過拍腦袋或是經驗值來設定,倒不如通過實際的故障測試來進行微調,比如對於下游出現超時情況,就可以通過實驗得出基於線程池限流到底要填寫多少數值。

應用啟動順序:理想情況下,應用啟動更應該做到 0 強依賴啟動。不過有一些情況無法做到。因此應用啟動的依賴順序也需要實時關注。特別是新 IDC、機房建站時,那個蜘蛛網一樣的依賴關係,最好是通過系統方式獲得。

故障根源定位:後台系統的故障,往往通過上一層的業務故障表現出來。故障處理講究的是爭分多秒,良好的強弱依賴,對於系統自動化診斷有非常大的助力作用。

依賴容量評估:正常調用鏈路下系統容量需要評估,當某個弱依賴掛掉時,整體的容量是否有變化。

說完背景,終於可以聊一下強弱依賴的技術實現。在阿里,強弱依賴的技術演進整體上分了 3 個階段,每個階段的方案的誕生都有其獨特的時代背景和業務難點。現在回頭看來,也可以看到當時技術的局限性和突破。

熟悉淘寶技術發展史的同學都知道,2008 年阿里剛剛完成一個代號為五彩石的項目,完成從巨石系統向服務化系統的改造。業務和開發模式上有了較大的發展,不過網狀的依賴關係也帶來了非常多的問題。這個紀元的主要特點是:故障頻發,技術思路和方法都是以結果為導向,糙一點、結果精度差一點可以忍受。

模擬依賴故障技術上有三招,改代碼 + 發布,遠程 Debug+ 重啟,登陸機器去執行一些 shell 命令操作。 好處是靈活隨意,可以一定程度達到效果;壞處是成本高,影響環境穩定,你測試的時候其他人處於無法工作狀態,影響效率。此外,這個階段,因為分布式鏈路追蹤技術還沒起步,所以模擬依賴故障時,經常會漏掉一些主機或某些服務。故障的粒度也比較粗,對於一些 Linux 的命令,都是主機級別的。

阿里內部有一套日常環境,主要做上線前的集成測試。為了盡量減少對環境的影響。我們通過修改服務版本的方式,形成一個獨立的測試環境。記得 11 年下半年,我開始做第一版的時候,我搭了淘寶 12 個核心應用的日常環境,踩坑無數,純體力活,也算前無古人,後無來者了。

通過這套環境跑了幾次結果,發給核心的業務 TL,大家很興奮,貌似找到一條治理的路子。不過很快暴露了新問題,比如環境的運維歸屬問題,開發機器的干擾問題,以及對於業務的了解程度和測試粒度問題,所以在很長一段時間測試的範圍都局限在交易核心鏈路。

第二個階段的核心就是提效,從第一個階段的痛點入手,解決人的成本和環境的問題。這個階段之後,基本可以擺脫手工方式,效率上有大幅度提升。

這個階段也引入了一些測試技術,其中用的比較多的是 Selenium,通過這種技術可以提前錄製用戶行為並轉化為測試腳本,並且每一個步驟都可以截圖記錄,方便問題複查。

在這個時期,阿里中間件的技術有一定發展,分布式追蹤技術出現,可以把用戶訪問的鏈條串聯起來,排查問題的效率有了一定提升。同時所有的中間件,如 Nginx、消息、分布式服務調用、分布式資料庫、軟負載和配置中心等都做了改造,支持用戶流量的標記、追蹤和路由控制。基於上述這些技術進展,環境的問題就有非常大的突破。

在內部我們稱為叫二套環境。它的核心原理是在基礎環境之上,動態區分出一些小環境,他們分別是某個業務的子集。項目之間彼此獨立,不會互相調用,只有當依賴的服務不在時,才會去訪問基礎環境的服務。資料庫和緩存是公用的。

在這個階段,我們不必再去修改代碼的服務版本,每次發布後,代碼的版本等能夠自動化的保持一致,運維成本有所降低,野服務干擾的情況也有所緩解,人的介入非常的少。不過還是有一些問題亟待解決:

首先,二套環境的路由策略是和用戶綁定的,也就是說需要提前去做一些配置;其次,域名上也有一些限制,加了 second 等前綴,測試路徑中 URL 等復用率低的問題沒有完全解決;第三,測試的粒度仍然很粗,獨佔機器,規模化推廣時,機器成本和用例運行的成本還是很高;第四,故障場景缺失,只存在於基礎環境的服務沒法模擬的故障,如:資料庫故障,緩存故障等。

2014 年的時候,我們的思維方式有了比較大的突破。我們不再糾結於環境和外部手段的改進,而是回歸到強弱依賴關注最核心的部分。那就是業務影響和系統設計。能否實現一種只與代碼設計和業務相關,而與外部環境無關的方案呢?

這期間有兩個關鍵思路或是推論:

推論 1:我們要的是下游依賴出現故障現象,不必真的是下游服務提供方出現故障。只要消費方感覺下游出現故障即可。從這個思路來講,商品詳情如果要做強弱依賴測試,只要自己玩就 OK,不需要去折騰下游依賴的幾十個應用。

推論 2:我們之所以需要單獨搭建環境,為的就是控制故障的影響範圍。那麼我們可以換一下思路,就是我們隻影響要發生故障的請求,其他的業務流量都放過。是不是就可以達到目的。本質上是一種對業務流量的篩查能力。

有了上面的思路,第一問題就是如何攔截用戶的請求?攔截用戶請求,讓用戶改造成本最低,沒有什麼地方比中間件更適合了。每個通用的遠程調用介面,都是可以做文章的點,並且中間件之上的業務系統不用做任何改造。

下一個問題就是故障規則和業務識別,我們曾考慮在用戶請求的入口就打上標記,置入故障規則,不過發現對於 post 請求,非同步 js 請求,定時任務等都有比較大的改造成本,且有安全隱患。 所以就增加了一個服務端,直接下發故障規則到依賴插件上。

故障插件通過對流量的調用攔截 + 業務識別,唯一確定影響哪一個請求,然後通過故障規則判斷是注入異常還是超時,從而達到模擬故障的效果。 因為插件可擴展的設計,所以我們默認是可以同時注入多種故障場景的,同時插件也會把影響到請求的詳細信息非同步上報給服務端做分析。

理論上通過上述的方案,在業務流量輸入方面,我們沒有任何要求。無論是人的自發測試行為,還是機器的測試行為,都沒有任何限制。只不過為最大限度復用已有的測試用例積累,提高自動化程度,我們設計了一套用例註解,封裝了和強弱依賴服務端的通信。利用 Junit 生命周期的特點,完成故障規則的下發和清除。

任何一個測試用例,20 秒之內改造成一個強弱依賴的測試用例。在結果輸出方面,會詳細的展示一次強弱依賴檢測的過程,以及測試用例涉及到的鏈路的依賴變化。到此階段,強弱依賴真正達到了一個相對里程碑的版本,2014 年開始,強弱依賴也作為雙 11 必做的一個橫向項目。

下面是強弱依賴註解和依賴系統的示例:

總的來說,整個強弱依賴技術演進歷史,就是對數據準確性,穩定性,成本、效率的不懈追求,並在這幾者之間達成一個動態平衡。

故障演練的基本原則和最佳系統設計實踐

眾所周知,2017 年不大太平,業界出現了很多大故障。

2017 年 3 月 1 日,弗吉尼亞州數據中心出現故障,亞馬遜 S3 服務出現了較高的錯誤率,直接影響到成千上萬個在線服務;2017 年 1 月 31 日, GibLab 同學線上資料庫變更時,遇到突發了一個情況。因為操作失誤,導致整個生產資料庫被誤刪除,丟失 6 個小時的數據;

2017 年 2 月份國內的一家經常被用來測試網路連通性的友商也出現了故障,工信部迅速關注,並緊急約談了相關公司。同時下發緊急通知要求 BAT 等各重點互聯網企業吸取教訓,業界一片嘩然。

這時候,有一家公司顯得特別淡定,那就是 Netflix。 Netflix 是一家服務全球的在線影片租賃提供商,他的核心業務完全架設在 AWS 上面。據新聞揭露,Netflix 在亞馬遜故障時可以很快的恢復正常,因為他們內部有一個"防故障"的基礎設施。聽起來,好像是我們需要的東西。

深入調查之後,發現防故障基礎設施背後是一個猴子軍團。

早在 2012 年,Netflix 就發布了 Chaos Monkey。用來在隨機殺死實例,據官方數據指出,到目前累計殺死 65,000 個節點。他們的測試策略也比較有趣:在工作時間在生產和測試環境運行,目標測試系統的健壯性,訓練後備人員,讓恢復更簡潔、快速、自動;Latency Monkey 的作用就是讓某台機器的請求或返回變慢,觀察系統的表現; Chaos Gorilla 的能力是搞掛一個機房,宏觀驗證業務容災和恢復的能力。Netflix 發布猴子軍團的原因是因為,他們很早就吃過雲故障的虧,所以本能是認為雲設施是不可靠的,必須在通過演練來驗證軟體層面的容災。

古代有個哲學家說過"沒有人曾經兩次踏進同一條河流",因為無論是這條河還是這個人都已不同。故障也是類似的,故障發生的時間地點,影響流量,與故障打交道的人都沒法完全相同。從這個角度看,故障治理本身是一個偽命題,都是在解決過去某一個時刻的問題。

不過從程序員視角(我習慣叫上帝視角),任何故障的原因都是可被定位的,避免相同原因重複引發故障,是每個程序員應該執著追求的目標。電商歷史上遇到了非常多有代表性的故障,為了不讓故障重複發生,阿里內部也打造了一套"防故障"的基礎設施。

2015 年 5 月 27 日,因為光纖中斷的問題,支付寶大規模宕機事故,公司內部得出一個結論:任何基礎設施、生產系統、任何流程都可能出現問題,沒有經過重大災難驗證的容災設施都是耍流氓。 啟動了代號為虎虎虎的生產突襲項目,用來驗證異地多活的質量。

2012 年,完成交易的同城雙活後,就啟動了同城容災演練,也叫斷網演練。驗證核心系統的同城一個機房掛掉的情況下,是否還可以正常工作。

2011 年,開始做強弱依賴的治理和建設,希望提前發現因為依賴問題導致的系統故障,系統的代號是 EOS(出處是古希臘神話中的黎明女神,語意是能夠把紛亂的依賴關係梳理清楚)。

可以看到,這三大件和 Netflix 的猴子軍團從功能上基本上是對標的。那是不是就應該沒有故障,安枕無憂了呢? 答案鐵定不是。

理想很豐滿,現實很骨感。阿里巴巴因為其多元化的業務場景和日益複雜的技術架構,會遇到各式各樣的故障,故障治理的難度相比流媒體服務故障治理,難度是也增量了幾個台階。

前面介紹過的強弱依賴和容災演練只能覆蓋到部分故障。如果對故障整體做初步畫像,故障整體可以分為 IaaS 層、PaaS 層、SaaS 層的故障,每一層都可能有很多故障觸發原因和表現。那麼對於這麼多種類繁雜的故障,內心一定是懵逼的。我們要如何重現,進而避免這麼多繁雜的故障呢?

熟悉三體的同學應該聽說過"降維攻擊"這個詞,不妨讓我們把維度降低一下,換一個視角看故障:

任何故障,一定是硬體如 IaaS 層,軟體如 PaaS 或 SaaS 的故障。 並且有個規律,硬體故障的現象,一定可以在軟體故障現象上有所體現。

故障一定隸屬於單機或是分布式系統之一,分布式故障包含單機故障。

對於單機或同機型的故障,以系統為視角,故障可能是當前進程內的故障,比如:如 FullGC,CPU 飆高; 進程外的故障,比如其他進程突然搶佔了內存,導致當前系統異常等。

同時,還可能有一類故障,可能是人為失誤,或流程失當導致,這部分我們今天不做重點討論。

任何故障都可以套入到這個故障模型中。有了這個模型,我們就可以開始來設計模擬故障的演練系統。

所以在內部,我們起了一個代號叫做"大聖歸來"的項目,項目名叫做"故障演練",承載的產品叫做 MonkeyKing。MonkeyKing 是中國美猴王的意思,看重的是孫悟空高強的本領(火眼精金、七十二變)和極具反叛的精神來,希望用一種創新的思路來保證穩定性。

我們的系統實現,也是圍繞前文討論的故障模型來設計的:

在客戶機器部署 OS 層的故障插件,用來模擬硬體層的故障和單機進程外的故障。

對於應用進程內的故障,提供插拔式的故障插件,也可以用戶按照我們的故障 API 做自己的實現。

對於分布式故障,則通過服務端按照 IP 來控制故障的範圍。

對於一些因為各種原因無法觸及的應用,比如資料庫。我們提供了一個故障三方實現的標準,供故障服務接入。

通過上面的方式,基本上就把技術型故障的模型就 cover 全了。

在去年的雙 11 中,故障演練的應用場景主要應用在圖中的幾個場景。 按照業務流量、壓測流量的峰值可以劃為 4 個象限。具體案例如下:

預案有效性:過去的預案測試的時候,線上沒有問題,所以就算測試結果符合預期,也有可能是有意外但是現象被掩藏了。

監控報警:報警的有無、提示消息是否準確、報警實效是 5 分鐘還是半小時、收報警的人是否轉崗、手機是否欠費等,都是可以 check 的點。

故障復現:故障的後續 Action 是否真的有效,完成質量如何,只有真實重現和驗證,才能完成閉環。發生過的故障也應該時常拉出來練練,看是否有劣化趨勢。

架構容災測試:主備切換、負載均衡,流量調度等為了容災而存在的手段的時效和效果,容災手段本身健壯性如何。

參數調優:限流的策略調優、報警的閾值、超時值設置等。

故障模型訓練:有針對性的製造一些故障,給做故障定位的系統製造數據。

故障突襲、聯合演練:通過藍軍、紅軍的方式鍛煉隊伍,以戰養兵,提升 DevOps 能力。

故障演練宣言:把故障以場景化的方式沉澱,以可控成本在線上模擬故障,讓系統和工程師平時有更多實戰機會 ,加速系統、工具、流程、人員的進步。

關於未來:

故障演練的後續工作主要會關注在以下方向:演練常態化、故障標類化、演練智能化。用常態化的演練驅動穩定性進步,而不是大促前進行補習;豐富更多的故障場景,定義好最小故障場景和處理手段;基於架構和業務分析的智能化演練,沉澱行業故障演練解決方案。

作者介紹

周洋,花名中亭,阿里巴巴技術專家。2011 年加入阿里巴巴中間件 & 高可用架構團隊,一直從事穩定性產品研發和架構升級的相關的工作,主導了強弱依賴、灰度發布、線上故障演練等多款高可用產品的研發和建設,見證了阿里高可用產品體系從 1.0 到 3.0 的發展歷程,積累了豐富的架構和穩定性經驗。2015 年作為共享事業部的大促 PM,負責大促和常態穩定性的保障工作。

今日薦文

點擊展開全文

喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 InfoQ 的精彩文章:

運維技術大盤點,2017 你該關注運維的哪一面?
為什麼說Spring REST是中高級Java工程師必備的核心技能?
想要提升移動網頁的載入速度?你可以Get這些技能
技術團隊里什麼樣的人會被清除?搶老闆的工作干合適嗎?
人工智慧路上,架構師的選擇和系列實踐

TAG:InfoQ |

您可能感興趣

遼寧艦編隊開展實戰化對抗演練 體系化訓練逐步常態化
應急支援運輸保障實戰化演練跨軍種展開
一線關注︱大化公路管理局開展消防安全演練活動
西藏公安消防總隊開展寺廟文物古建築滅火救援實戰演練
謀糧草之道 練後勤之能——伊犁支隊開展戰勤保障實戰拉動演練
這樣的戰備綜合演練,實!
印度阿瓊坦克實戰演練
俄羅斯偵察兵展開實戰化集訓,演練各種技能,動作是迅速勇猛
堪稱大片!偵察系統、滅火機器人等黑科技投入救災綜合演練
聖甲蟲戰術導彈部隊實戰演練現場
我區成功開展戰備鋼橋實裝架設演練活動
解放軍空、地實彈聯合作戰,空中突擊部隊展開立體奪控演練!
披堅執銳。南博安保警務實戰演練
以色列無人機的實戰演練(上)
以色列無人機的實戰演練(下)
一場逼真的演練-煤礦透水事故救援演習紀實
益陽市舉辦大型綜合市場滅火救援實戰演練
俄羅斯空降兵和白俄羅斯特種部隊在聯合演練時進行偽裝偵察演練
【嗜血軍團】個人新春混沌皮膚實戰演練
我駐吉布地保障基地開展實兵實裝實彈演練