【DevOps入門】不知道DevOps從哪里起步?從代碼重構(gòu)和韌性構(gòu)建開始 v0.7

代碼重構(gòu)、韌性構(gòu)建與DevOps的關(guān)系

作為一個(gè)有DevOps追求的程序員,你的目標(biāo),肯定是要讓代碼能在生產(chǎn)環(huán)境中,持續(xù)穩(wěn)定地為用戶提供良好服務(wù)。

但是該如何起步DevOps呢?你決定先看看代碼再說。

但當(dāng)你擼起袖子翻開祖?zhèn)鞯拇a后,心里就涼了半截。因?yàn)榇a實(shí)在是難以理解和維護(hù)。

于是,你買來老馬的《重構(gòu)》第2版,苦修代碼重構(gòu)。另外還學(xué)習(xí)和實(shí)踐了整潔代碼、測(cè)試驅(qū)動(dòng)開發(fā)、持續(xù)集成和持續(xù)交付。

功夫不負(fù)有心人,祖?zhèn)鞔a在你手上,開始變得更可讀,更易維護(hù)。

你還暖心地增加了覆蓋關(guān)鍵業(yè)務(wù)的自動(dòng)化測(cè)試,并且上了流水線,每次代碼提交就能跑上一次。

如果流水線變紅,10分鐘內(nèi)你就能修復(fù)。

當(dāng)你正為自己感到自豪的時(shí)候,意外發(fā)生了。

你所參與開發(fā)的系統(tǒng),在生產(chǎn)環(huán)境出現(xiàn)了嚴(yán)重的事故——用戶無法登錄系統(tǒng)。

運(yùn)維人員用了大半天時(shí)間,把公司所開發(fā)的所有系統(tǒng)都重啟了一遍,但依然無濟(jì)于事。

最后,一個(gè)運(yùn)維人員無意中發(fā)現(xiàn),一個(gè)生產(chǎn)系統(tǒng)所依賴的外部系統(tǒng),發(fā)生了死機(jī)。

這導(dǎo)致了層疊失效,并波及到你所開發(fā)的模塊,并最終把整個(gè)系統(tǒng)拖垮。

為什么會(huì)這樣?因?yàn)槟惝?dāng)時(shí)在開發(fā)時(shí),總是假設(shè)所依賴的外部系統(tǒng),從來不會(huì)死機(jī)。這樣就沒有設(shè)計(jì)超時(shí)或斷路器等機(jī)制,來應(yīng)對(duì)這種未知的失效場(chǎng)景。

這時(shí),你開始意識(shí)到,代碼重構(gòu)是面向已知場(chǎng)景的。所以無法發(fā)現(xiàn)未知場(chǎng)景的漏洞。

代碼重構(gòu)的下一站:韌性構(gòu)建

你翻開《重構(gòu)》,找到了重構(gòu)的定義。

重構(gòu),是對(duì)軟件內(nèi)部結(jié)構(gòu)的一種調(diào)整,目的是在不改變軟件可觀察行為的前提下,提高其可理解性,降低其修改成本。

定義里面的“不改變軟件可觀察行為”,就意味著重構(gòu)所涉及的軟件行為,必然是已知的,否則就無法判斷是否改變了該行為。

上圖有4個(gè)象限。

第1象限,已知的已知行為,就好比用紙疊一架紙飛機(jī)一樣,一切盡在掌握。

這就像在程序員本機(jī)運(yùn)行單元測(cè)試,或修復(fù)靜態(tài)掃描出來的技術(shù)債一樣。測(cè)試用例和技術(shù)債,都是已知的。

第2象限,未知的已知行為,就好比一邊聽音樂一邊外出鎖門那樣,自己都不知道自己已經(jīng)把門鎖得好好的。

當(dāng)你養(yǎng)成了重構(gòu)和整潔代碼的習(xí)慣,也會(huì)到達(dá)“未知的已知行為”的境界。

第3象限,已知的未知行為,就好比一個(gè)最近半年因?yàn)橐咔樵诩疑暇W(wǎng)課很久的高三學(xué)生,知道今年的高考一定很特別,但就是不知道特別在哪里一樣。

當(dāng)過程序員的都知道,當(dāng)你寫完所負(fù)責(zé)的模塊,第一次在測(cè)試環(huán)境中進(jìn)行集成測(cè)試,就會(huì)預(yù)感到,因?yàn)樗蕾嚨哪K可能沒有遵循契約,或測(cè)試環(huán)境的配置可能有錯(cuò)誤,會(huì)出現(xiàn)各種狀況,但你不知道具體會(huì)碰到什么狀況。但測(cè)試環(huán)境還是相對(duì)簡單的,而且用戶一般就你一個(gè)人,所以你能估計(jì)出一些常見的問題,所以這還算“已知的未知行為”。

第4象限,未知的未知行為。就好比你現(xiàn)在正在北京豐臺(tái)區(qū),你真的不知道明天疫情會(huì)出現(xiàn)怎樣的發(fā)展。

與疫情的不確定性相比,生產(chǎn)環(huán)境的不確定性一點(diǎn)也不少——用戶會(huì)不會(huì)一窩蜂地點(diǎn)擊“重試”按鈕?生產(chǎn)系統(tǒng)所依賴的外部系統(tǒng)的響應(yīng)會(huì)不會(huì)突然出現(xiàn)延遲,或者違反了契約?生產(chǎn)環(huán)境所依賴的包,會(huì)不會(huì)有內(nèi)存泄露?……林林總總,你真的是兩眼一抹黑。

那該如何發(fā)現(xiàn)未知的漏洞呢?

能靠人事先評(píng)估出來嗎?不能。因?yàn)槿绻?,那還算“未知的未知行為”嗎?你能事先評(píng)估出海鮮市場(chǎng)會(huì)爆發(fā)疫情嗎?

之前未知的漏洞,只能靠系統(tǒng)在實(shí)際運(yùn)行時(shí)暴露出來。

讓系統(tǒng)在實(shí)際運(yùn)行時(shí)暴露出漏洞,也分“被動(dòng)”和“主動(dòng)”兩種情況。

比如生產(chǎn)事故,以及今年北京新發(fā)地農(nóng)場(chǎng)品批發(fā)市場(chǎng)所發(fā)現(xiàn)的疫情,都屬于被動(dòng)暴露漏洞。雖然被動(dòng),但確實(shí)能發(fā)現(xiàn)未知的漏洞。

雖然被動(dòng)的方式能發(fā)現(xiàn)未知的漏洞,但是以生產(chǎn)事故或確診染病為代價(jià)的,成本較高。

有沒有主動(dòng)發(fā)現(xiàn)未知漏洞的方法?有的,變著花樣多考驗(yàn)生產(chǎn)系統(tǒng)就行。比如西游記中四圣試禪心那樣,變成母女四人,主動(dòng)考驗(yàn)師徒四人。又比如北京目前在居民小區(qū)所進(jìn)行的大規(guī)模核酸檢測(cè)篩查,也是主動(dòng)考驗(yàn)居民健康狀態(tài)的一種形式。

你彌補(bǔ)了上次生產(chǎn)事故所暴露的漏洞。

接下來,你針對(duì)這個(gè)有可能會(huì)停機(jī)的外部系統(tǒng),設(shè)計(jì)了能限制爆炸半徑的災(zāi)難恢復(fù)測(cè)試——一旦這個(gè)外部系統(tǒng)停機(jī),生產(chǎn)系統(tǒng)可以為用戶發(fā)出提示信息,而不至于一起死機(jī)。

為防范災(zāi)難恢復(fù)測(cè)試中的意外,你還設(shè)計(jì)了能讓測(cè)試緊急中止的應(yīng)急機(jī)制。

你先在測(cè)試環(huán)境中運(yùn)行通過了這個(gè)災(zāi)難恢復(fù)測(cè)試,然后又在生產(chǎn)環(huán)境上運(yùn)行通過。這驗(yàn)證了漏洞確實(shí)被補(bǔ)上了。

你還將這個(gè)災(zāi)難恢復(fù)測(cè)試進(jìn)行了自動(dòng)化,使其能持續(xù)運(yùn)行,以驗(yàn)證漏洞不會(huì)再漏。

為了引導(dǎo)大家發(fā)現(xiàn)更有價(jià)值的未知漏洞,你還召開了“考驗(yàn)會(huì)”,即讓團(tuán)隊(duì)成員,根據(jù)生產(chǎn)環(huán)境可能出現(xiàn)的考驗(yàn)場(chǎng)景發(fā)生頻次、概率和經(jīng)受考驗(yàn)的信心,排序選出最應(yīng)優(yōu)先進(jìn)行的考驗(yàn),并為其設(shè)計(jì)災(zāi)難恢復(fù)測(cè)試,來驗(yàn)證考驗(yàn)?zāi)芊裢ㄟ^,以及在考驗(yàn)中發(fā)現(xiàn)未知的漏洞。

這樣,你就實(shí)現(xiàn)了面向未知漏洞的系統(tǒng)的韌性(Resilience)構(gòu)建。

韌性,來源于“韌性工程”(Resilience Engineering,也稱作“彈性工程”),指系統(tǒng)在生產(chǎn)環(huán)境的動(dòng)蕩(包括變更、干擾和機(jī)會(huì))發(fā)生之前、之中和之后,都能相應(yīng)調(diào)整其功能,從而在預(yù)期和意外的情況下,仍然可以保持可做出所需操作的能力。

有關(guān)構(gòu)建韌性的更多信息,參見【混沌工程入門】領(lǐng)導(dǎo)讓我做混沌工程……該咋做?。

通過上面的故事,你獲得了以下啟示:

代碼重構(gòu),能讓代碼更易讀和更易維護(hù),讓以后的漏洞修補(bǔ)更加快速。在流水線上運(yùn)行自動(dòng)化測(cè)試,能發(fā)現(xiàn)和修復(fù)已知的漏洞。

韌性構(gòu)建,能通過生產(chǎn)事故,及在測(cè)試環(huán)境或生產(chǎn)環(huán)境所進(jìn)行的精心設(shè)計(jì)的考驗(yàn)(比如運(yùn)行災(zāi)難恢復(fù)測(cè)試),來發(fā)現(xiàn)并修復(fù)未知的漏洞。如將災(zāi)難恢復(fù)測(cè)試自動(dòng)化,且持續(xù)運(yùn)行,能驗(yàn)證漏洞不會(huì)再漏。

代碼重構(gòu)的下一站,就是應(yīng)對(duì)未知漏洞的韌性構(gòu)建,是向DevOps邁出的更大一步。

針對(duì)已知行為的代碼重構(gòu),為針對(duì)未知行為的韌性構(gòu)建,創(chuàng)造了易理解和易維護(hù)的代碼庫,以便分析未知漏洞。

而韌性構(gòu)建,能將所發(fā)現(xiàn)的未知漏洞,轉(zhuǎn)化為已知的軟件可觀察行為,進(jìn)行重構(gòu),以修復(fù)漏洞。

代碼重構(gòu),一般發(fā)生在本機(jī)或開發(fā)環(huán)境,主要由Dev來完成。

韌性構(gòu)建,一般發(fā)生在測(cè)試環(huán)境與生產(chǎn)環(huán)境,主要由Dev和Ops一起協(xié)作,來定義系統(tǒng)穩(wěn)態(tài)行為的假設(shè),設(shè)計(jì)一系列災(zāi)難恢復(fù)測(cè)試,來考驗(yàn)系統(tǒng)在未知?jiǎng)邮幭碌捻g性,并在災(zāi)難恢復(fù)測(cè)試進(jìn)行時(shí),搜集系統(tǒng)穩(wěn)態(tài)相關(guān)的數(shù)據(jù),以便發(fā)現(xiàn)并修復(fù)未知的漏洞。由此可見,這需要Dev與Ops的密切協(xié)作。

兩者的有機(jī)結(jié)合,能彌補(bǔ)軟件系統(tǒng)已知和未知漏洞,從而更好地讓代碼,能在生產(chǎn)環(huán)境持續(xù)穩(wěn)定地為用戶提供良好服務(wù)。

如果你聽了很久DevOps,但不知該從何做起,那么可以嘗試從“代碼重構(gòu)”和“韌性構(gòu)建”,開始你的DevOps之旅。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容