被變更逼瘋的碼農(nóng),是如何成功自救的?
干貨概覽
作為一個(gè)合格的碼農(nóng),我們每時(shí)每刻都在為開發(fā)新功能、修復(fù)Bug、提升系統(tǒng)性能揮灑汗水。變更發(fā)布是產(chǎn)品迭代的必經(jīng)之路,但是變化總伴隨著風(fēng)險(xiǎn),互聯(lián)網(wǎng)公司轟動(dòng)一時(shí)發(fā)生的大故障,往往跟變更有關(guān)。一半以上的故障是由變更引入的,毫無疑問,減少變更引入的故障能夠顯著提升服務(wù)的穩(wěn)定性。
減少變更引入故障的基本方法是規(guī)范開發(fā)流程、提升開發(fā)質(zhì)量、加強(qiáng)QA測試環(huán)節(jié),從而避免將有問題的版本發(fā)布到線上,防患于未然。但是,由于線上環(huán)境與測試環(huán)境往往存在差異,一些變更在測試環(huán)境中工作正常,但是在線上環(huán)境會(huì)暴露出故障。這些變更成為了薛定諤的貓,只有在上線后才能揭曉是否存在故障。
因此,在發(fā)布過程中對(duì)服務(wù)健康情況進(jìn)行跟蹤檢查、及早發(fā)現(xiàn)變更引入的故障成為發(fā)布過程不可或缺的環(huán)節(jié),這樣才能避免系統(tǒng)卷入重大故障的血案中。本文將介紹百度是如何對(duì)變更發(fā)布進(jìn)行分級(jí)、檢查來控制變更故障影響范圍的。
分級(jí)發(fā)布,讓故障影響范圍可控
在百度,我們采用分級(jí)發(fā)布機(jī)制來發(fā)布變更到線上環(huán)境。分級(jí)發(fā)布將變更發(fā)布過程拆分成多個(gè)階段,每個(gè)階段只將變更應(yīng)用到部分機(jī)器上,并在相鄰的兩個(gè)階段之間對(duì)服務(wù)的健康情況進(jìn)行檢查。如果發(fā)現(xiàn)服務(wù)的健康度顯著下降,則可以中止甚至回滾變更。在這個(gè)過程當(dāng)中,大部分故障都能夠在最后一個(gè)階段之前被發(fā)現(xiàn),因此故障通常只影響已經(jīng)應(yīng)用了變更的部分機(jī)器,從而有效地控制了故障的影響范圍。
分級(jí)發(fā)布拆分的階段越多,越能夠在變更全面應(yīng)用之前發(fā)現(xiàn)問題。但是,階段的數(shù)量也并非越多越好,因?yàn)槊總€(gè)階段都需要花費(fèi)一定的時(shí)間來應(yīng)用變更和檢查健康度,階段的數(shù)量大必然導(dǎo)致發(fā)布的時(shí)間變長,從而降低發(fā)布的效率。圖1給出了百度內(nèi)部分級(jí)發(fā)布的最佳實(shí)踐方案。
方案包含5個(gè)階段,依次為沙盒環(huán)境、單機(jī)房少量機(jī)器、單機(jī)房全量機(jī)器、其他所有機(jī)房少量機(jī)器、以及其他所有機(jī)房全量機(jī)器。這種劃分方法平衡了故障風(fēng)險(xiǎn)和變更發(fā)布效率,在每個(gè)階段制定了對(duì)應(yīng)的故障止損預(yù)案,在實(shí)踐中取得了很好的效果。
將變更發(fā)布過程拆分成多個(gè)階段是基礎(chǔ),相鄰的兩個(gè)階段之間服務(wù)健康度檢查是核心。如果在各階段發(fā)布后未進(jìn)行服務(wù)健康度檢查或者檢查方法無效,即使將變更發(fā)布劃分成了多個(gè)階段,故障最終將擴(kuò)展到所有機(jī)器。
因此,分級(jí)發(fā)布檢查是否有效直接決定了故障引發(fā)的損失量。下面將重點(diǎn)介紹如何進(jìn)行分級(jí)發(fā)布檢查。
更快、更準(zhǔn)發(fā)現(xiàn)變更潛在隱患
1. 人工檢查,變更發(fā)布效率無法保證
人工檢查是最容易想到的檢查方法,當(dāng)一個(gè)階段變更發(fā)布結(jié)束后,運(yùn)維工程師會(huì)去監(jiān)控平臺(tái)對(duì)核心指標(biāo)的波動(dòng)情況進(jìn)行逐一檢查。如發(fā)現(xiàn)有波動(dòng)異常的指標(biāo),則認(rèn)為本次變更存在問題,中止甚至回滾變更。
在百度,運(yùn)維工程師會(huì)檢查CPU等系統(tǒng)指標(biāo)以及請(qǐng)求量等業(yè)務(wù)指標(biāo),需要檢查的核心指標(biāo)個(gè)數(shù)一般在300個(gè)以上。為了保證變更發(fā)布效率,一次變更發(fā)布除去機(jī)器重啟的時(shí)間,留給人工檢查的時(shí)間通常只有10分鐘左右。根據(jù)上述的分級(jí)發(fā)布流程,一共存在4個(gè)檢查點(diǎn),這就意味著要保證變更發(fā)布效率,運(yùn)維工程師需要在0.5(10*60/4/300)秒內(nèi)完成一個(gè)指標(biāo)的檢查。
我們知道,在對(duì)指標(biāo)檢查的時(shí)候,不單要看當(dāng)前的波動(dòng),還要參考指標(biāo)在歷史上的波動(dòng)情況,0.5秒完成一個(gè)指標(biāo)的檢查人工是無法做到的。
2. 基于人工規(guī)則檢查,閾值選擇、更新是難題
每次變更發(fā)布后人工檢查核心指標(biāo)耗時(shí)耗力,能否將人工檢查的經(jīng)驗(yàn)轉(zhuǎn)化成規(guī)則,變更發(fā)布時(shí)基于規(guī)則進(jìn)行自動(dòng)檢查?這就是基于人工規(guī)則自動(dòng)檢查。首先,人工根據(jù)指標(biāo)的波動(dòng)情況,給指標(biāo)設(shè)定不同的閾值。當(dāng)服務(wù)變更發(fā)布后,會(huì)自動(dòng)啟動(dòng)服務(wù)健康狀態(tài)檢查腳本,腳本會(huì)將當(dāng)時(shí)的指標(biāo)采集值與人工設(shè)置的閾值進(jìn)行比較,若存在指標(biāo)采集值未落入人工配置的閾值范圍內(nèi),則判斷本次變更可能引入了故障,中止變更并通知運(yùn)維同學(xué)進(jìn)行處理。
如圖2所示的兩個(gè)指標(biāo),人工給請(qǐng)求量指標(biāo)設(shè)置的閾值上界為2.2k、下界為1.5k;對(duì)于請(qǐng)求失敗數(shù)指標(biāo),用戶只關(guān)心指標(biāo)上漲,因此給指標(biāo)設(shè)置了20的上界。變更發(fā)布后,請(qǐng)求量指標(biāo)在1.5k ~ 2.2k之間波動(dòng),判斷該指標(biāo)正常;請(qǐng)求錯(cuò)誤數(shù)超過了人工配置的上界20,判斷該指標(biāo)異常,需要中止變更。
基于人工規(guī)則檢查將檢查過程自動(dòng)化,大幅提升了變更發(fā)布效率的同時(shí)也節(jié)省了人力成本。但是人工規(guī)則檢查面臨兩大難題:閾值選擇、閾值更新。
首先,應(yīng)該設(shè)置什么樣的閾值是一個(gè)很難回答的問題,圖3(a)為某服務(wù)的錯(cuò)誤日志數(shù)指標(biāo),人工根據(jù)經(jīng)驗(yàn)將閾值上界設(shè)為15,在一次變更發(fā)布后錯(cuò)誤數(shù)發(fā)生了明顯的上漲,但未達(dá)到人工設(shè)置的閾值,因此基于人工規(guī)則無法發(fā)現(xiàn)這次變更引入的故障,導(dǎo)致故障擴(kuò)散到所有機(jī)房,影響了服務(wù)的穩(wěn)定性。
另外,人工配置閾值也并非一勞永逸,當(dāng)指標(biāo)水位發(fā)生變化后,需要對(duì)閾值進(jìn)行更新。如圖(b)是某服務(wù)的請(qǐng)求量指標(biāo),歷史請(qǐng)求量經(jīng)常維持在1.3k,人工將閾值設(shè)置在1.2 ~ 1.4k。隨著業(yè)務(wù)的發(fā)展,服務(wù)的請(qǐng)求量有了突增達(dá)到了1.6k,需要人工對(duì)閾值進(jìn)行調(diào)整。
3. 智能檢查,安心躺著做變更
鑒于人工規(guī)則檢查存在閾值選擇、更新困難的問題,迫切需要有更智能的檢查方法。我們對(duì)一些引入故障的變更進(jìn)行分析發(fā)現(xiàn),大部分的故障會(huì)導(dǎo)致指標(biāo)突變,運(yùn)維工程師往往對(duì)發(fā)生突變的指標(biāo)格外關(guān)注。同時(shí),我們也發(fā)現(xiàn),在變更場景下,指標(biāo)突變不一定代表變更引入了故障。
比如,當(dāng)在流量上漲期間進(jìn)行變更發(fā)布時(shí),流量相關(guān)的指標(biāo)必然會(huì)發(fā)生突增。再比如,在變更發(fā)布過程中伴隨著進(jìn)程重啟,像內(nèi)存、文件句柄等指標(biāo)可能會(huì)因?yàn)橘Y源釋放而發(fā)生突降。因此,智能檢查算法由兩部分組成:度量指標(biāo)是否發(fā)生突變、對(duì)突變是否合理進(jìn)行判斷。若指標(biāo)在變更發(fā)布前后發(fā)生了無法解釋的突變,則認(rèn)為指標(biāo)異常。
指標(biāo)突變是否合理可以從以下兩個(gè)角度進(jìn)行解釋:突變是否由時(shí)間因素、重啟導(dǎo)致。由于時(shí)間因素的影響會(huì)同時(shí)施加在應(yīng)用變更的機(jī)器(實(shí)驗(yàn)組)和未應(yīng)用變更的機(jī)器(對(duì)照組),可以根據(jù)對(duì)照組來排除時(shí)間因素的影響;進(jìn)程重啟對(duì)指標(biāo)的影響可以通過歷史變更來建模。當(dāng)對(duì)照組與歷史變更均無法解釋指標(biāo)突變時(shí),則認(rèn)為指標(biāo)異常,需要中止變更。智能檢查無需人工配置參數(shù),可以自動(dòng)、智能地識(shí)別異常突變的指標(biāo)。
圖4給出了一個(gè)具體的例子,每一行代表一個(gè)指標(biāo),對(duì)于每個(gè)指標(biāo)都展示了在某次變更發(fā)布前后的波動(dòng)情況、對(duì)照組在對(duì)應(yīng)時(shí)間的波動(dòng)情況以及指標(biāo)在歷史一次正常的變更發(fā)布前后的波動(dòng)情況。
對(duì)于指標(biāo)①,指標(biāo)在本次變更發(fā)布后出現(xiàn)了上漲,但是對(duì)照組也出現(xiàn)了類似程度的上漲,因此判斷上漲是由時(shí)間因素導(dǎo)致,指標(biāo)變化正常;對(duì)于指標(biāo)②,變更發(fā)布后指標(biāo)出現(xiàn)突降,歷史正常變更發(fā)布后指標(biāo)都會(huì)發(fā)生突降,因此判斷突降是由進(jìn)程重啟導(dǎo)致的,指標(biāo)變化正常;對(duì)于指標(biāo)③,變更發(fā)布后發(fā)生了突增,而對(duì)照組跟歷史變更發(fā)布后均未發(fā)生明顯變化,即指標(biāo)突變無法被對(duì)照組、歷史變更解釋,指標(biāo)異常,需要中止甚至回滾變更。
總結(jié)
以上就是我們使變更發(fā)布更加安全高效的方法,智能檢查算法是減少故障損失的核心。算法基于歷史變更和對(duì)照組進(jìn)行,不需要人工配置參數(shù),具有普適性。希望能夠?qū)Υ蠹矣兴鶐椭缬腥魏蜗敕ê鸵蓡枺瑲g迎一起交流。