點(diǎn)擊鏈接閱讀原文,獲取更多技術(shù)內(nèi)容:https://Developer.aliyun.com/article/1280668?utm_content=g_1000377741
在一個(gè)大型團(tuán)隊(duì)中,bug協(xié)同管理是一件復(fù)雜的事情,我們基于go-git開(kāi)發(fā)實(shí)現(xiàn)了通用化的git-poison,通過(guò)分布式源碼管理bug追溯、查詢(xún),可復(fù)制性高,適用于所有g(shù)it倉(cāng)庫(kù),與分支模式和代碼倉(cāng)庫(kù)無(wú)關(guān)。
作者 | 澄晏
來(lái)源 | 阿里開(kāi)發(fā)者公眾號(hào)
前言
在一個(gè)大型團(tuán)隊(duì)中,bug協(xié)同管理是一件復(fù)雜的事情,發(fā)布經(jīng)理要追版本bug,運(yùn)維同學(xué)要評(píng)估bug影響范圍,開(kāi)發(fā)同學(xué)要在多個(gè)開(kāi)發(fā)分支同時(shí)修復(fù)同一個(gè)bug,很容易出現(xiàn)bug漏提交、漏確認(rèn)等生產(chǎn)安全問(wèn)題。
本團(tuán)隊(duì)也出現(xiàn)過(guò)一起不同分支漏提交bugfix導(dǎo)致的一起P1故障(最高等級(jí)),該bug在生產(chǎn)環(huán)境進(jìn)行hotfix時(shí),漏掉了少量集群導(dǎo)致該二次故障。舉個(gè)相似的例子,某品牌汽車(chē)發(fā)現(xiàn)潛在安全隱患進(jìn)行召回,但卻遺漏了某個(gè)小地區(qū),偏偏在遺漏的地區(qū),發(fā)生了安全事故導(dǎo)致有人員傷亡。
我們基于go-git開(kāi)發(fā)實(shí)現(xiàn)了通用化的git-poison,通過(guò)分布式源碼管理bug追溯、查詢(xún),可復(fù)制性高,適用于所有g(shù)it倉(cāng)庫(kù),與分支模式和代碼倉(cāng)庫(kù)無(wú)關(guān)。bug管理不依賴(lài)人與人之間溝通協(xié)調(diào),降低了認(rèn)知負(fù)擔(dān)。
Bug為什么重復(fù)翻車(chē)
任何軟件都會(huì)有bug。即使再全面的測(cè)試,再細(xì)致的代碼review,也不能保證線(xiàn)上的每一段代碼都bug-free。但是已經(jīng)識(shí)別到的bug,為什么還會(huì)重復(fù)翻車(chē)呢?歸根結(jié)底,git多分支開(kāi)發(fā)模式會(huì)導(dǎo)致bug擴(kuò)散。引入bug和發(fā)現(xiàn)和修復(fù)bug的時(shí)間異步,口頭溝通確認(rèn)bug易疏漏。
很多人看到前言的故障可能會(huì)認(rèn)為,這只是“不小心”犯了個(gè)錯(cuò)誤,下次再“細(xì)心”一點(diǎn)兒就好了。其實(shí)不是的,在百人規(guī)模的團(tuán)隊(duì)中,人犯錯(cuò)可以說(shuō)是必然的。
上圖形象展示了人與人之間的協(xié)同成本。
10人團(tuán)隊(duì)的整體協(xié)同一次的溝通次數(shù)為90/2=45次,那么100人則是4650次。這個(gè)次數(shù)只是相互協(xié)同一次,大多數(shù)場(chǎng)景下,由于bug和bugfix是隨時(shí)出現(xiàn)的,再加上人的失誤 (溝通中忘了某些bug等),所以一般來(lái)講,一個(gè)發(fā)布流程至少需要前后同步三次,溝通成本巨大。
所以誰(shuí)能打包票,在這個(gè)流程中不犯錯(cuò)?只有通過(guò)工具來(lái)進(jìn)行自動(dòng)化管理才能保證從“不做錯(cuò)”到“做不錯(cuò)”。
幾個(gè)典型翻車(chē)場(chǎng)景
場(chǎng)景一:未修復(fù)bug代碼上線(xiàn)
圖2 發(fā)布同學(xué)多方協(xié)同
?微服務(wù)化盛行,系統(tǒng)各服務(wù)獨(dú)立發(fā)布,發(fā)布o(jì)wner也會(huì)選擇本組比較有經(jīng)驗(yàn)的同學(xué),但仍舊不能避免開(kāi)發(fā)與發(fā)布之間的信息割裂。該類(lèi)問(wèn)題有很多種表現(xiàn)形態(tài),舉例來(lái)說(shuō):
- 我是一名開(kāi)發(fā):我發(fā)現(xiàn)了一個(gè)新Bug,我得趕緊告訴版本發(fā)布負(fù)責(zé)人,叫停本次版本發(fā)布;
- 我是一名測(cè)試:我發(fā)現(xiàn)了一個(gè)新Bug,我需要評(píng)估線(xiàn)上該Bug受影響的范圍,安排hotfix;
- 我是一名運(yùn)維:我在調(diào)查一個(gè)生產(chǎn)問(wèn)題,我不知道這是不是一個(gè)已知問(wèn)題,我去問(wèn)問(wèn)開(kāi)發(fā);
版本發(fā)布同學(xué),作為整個(gè)流程的核心人物,在這個(gè)繁瑣的流程中極易犯錯(cuò)。
場(chǎng)景二:已修復(fù)bug但沒(méi)修全
還有一類(lèi)情況,就是針對(duì)分支開(kāi)發(fā)的代碼漏合。
圖3 分支開(kāi)發(fā)漏合bugfix
某一分支發(fā)現(xiàn)bug時(shí)(參考上圖branch master),第一時(shí)間一定會(huì)在master分支上進(jìn)行修復(fù)。然而此時(shí)帶有該bug的branch1就被遺漏了。該問(wèn)題在多個(gè)LTS(Long Time Support)分支的開(kāi)發(fā)模式中尤其嚴(yán)重,每個(gè)版本都需要發(fā)布同學(xué)double check有無(wú)重點(diǎn)bugfix漏合。
場(chǎng)景三:已修復(fù)bug線(xiàn)上漏發(fā)
這就是前言提到的場(chǎng)景。人為疏漏。
漏發(fā)確實(shí)是非常大的問(wèn)題,但是也有客觀(guān)原因。面對(duì)千萬(wàn)級(jí)別的生產(chǎn)環(huán)境,數(shù)十年多個(gè)生產(chǎn)版本共存,面臨這樣的組合爆炸,人肉確認(rèn)hotfix發(fā)布范圍不遺漏確實(shí)是很大的挑戰(zhàn)。
圖4 線(xiàn)上多種環(huán)境組合,發(fā)布同學(xué)易遺漏
如上圖,假如所有集群按物理ENV分為六組(線(xiàn)上生產(chǎn)遠(yuǎn)大于此),例子里本次發(fā)布bugfix的同學(xué)就是漏掉了ENV5的集群,已知bug也剛好在這個(gè)分組的集群中再次出現(xiàn)了。
發(fā)布卡點(diǎn)Bug信息
因此,應(yīng)當(dāng)存在全局角色來(lái)維護(hù)bug相關(guān)信息。任何角色、任何時(shí)間、任何地點(diǎn)都能夠編輯和訪(fǎng)問(wèn)。
無(wú)論是devops模式,還是傳統(tǒng)的專(zhuān)職“研發(fā),測(cè)試,運(yùn)維”模式,都會(huì)面臨負(fù)責(zé)發(fā)布的負(fù)責(zé)人,單點(diǎn)評(píng)估整個(gè)版本的bugfix以及確認(rèn)未修復(fù)bug,充當(dāng)“人肉pipeline”。作為一個(gè)分布式系統(tǒng)開(kāi)發(fā)人員,能否使用分布式工具來(lái)解決分布式溝通協(xié)同的老大難問(wèn)題呢?
git-poison的出現(xiàn),不僅能實(shí)時(shí)在“開(kāi)發(fā),測(cè)試,發(fā)布”間同步所有已知問(wèn)題,還能參與發(fā)布卡點(diǎn),確認(rèn)當(dāng)前版本的未修復(fù)bug信息,節(jié)約人力成本。
圖5 多方調(diào)用git-poison滿(mǎn)足需求
如何使用
git-poison基于go-git的分布式源碼管理,實(shí)現(xiàn)bug的追溯、查詢(xún)和反饋,靈活&&可復(fù)制性高,適用于任何開(kāi)發(fā)模式以及任意代碼倉(cāng)庫(kù)。另外,git-poison不依賴(lài)人與人之間的協(xié)作溝通,減少認(rèn)知負(fù)擔(dān)溝通成本,自動(dòng)化精準(zhǔn)召回bug中毒域,實(shí)現(xiàn)poison commit發(fā)布阻塞。
圖6 git-poison 投毒/解藥/銀針 (yum install git-poison)
對(duì)于開(kāi)發(fā)者,只需要記住一件事:抓緊投毒!
回到前言說(shuō)到的P1故障,使用git-poison就能簡(jiǎn)單有效避免“重復(fù)翻車(chē)”的場(chǎng)景:
- 值班:線(xiàn)上出現(xiàn)故障,定位問(wèn)題。使用git-posion投毒。
- 開(kāi)發(fā):bug修復(fù),使用git-poison解毒。
- 發(fā)布hotfix:發(fā)布完畢后,使用git-poison銀針,確保線(xiàn)上所有帶bug的版本,都帶有本次的bugfix。
如何實(shí)現(xiàn)
每一次投毒/解毒,git-poison的poisons遠(yuǎn)程git倉(cāng)庫(kù)中都會(huì)生成/更新一條對(duì)應(yīng)記錄。不同代碼倉(cāng)庫(kù)對(duì)應(yīng)不同分支,隔離不同源的posions信息。
{ "poison":"1q234tre5467gcs7yui8ew13", "cure":"9875jgbsw32gtx6djri8sofi0h", "comment":"[to #12345678] service iohang", "editor":"Iris",}
check-commit則應(yīng)用了git原生強(qiáng)大的history tree管理。?
圖7 紅色QW為毒藥commit下的git歷史DAG
如上圖,假如我們當(dāng)前在release分支上,上次的發(fā)布commit是B,當(dāng)前的發(fā)布commit是X。通過(guò) git rev-list 可以直接獲取到整個(gè)DAG(Directed Acyclic Graph)。結(jié)合git-poison的記錄,若紅色的Q和W是沒(méi)有解藥的poison,則git-poison會(huì)阻塞本次發(fā)布,返回投毒同學(xué)以及對(duì)應(yīng)bug的記錄文檔信息。
假如我們?cè)贒ev分支上查詢(xún)L是否“有毒”,則git-poison會(huì)返回“healthy”。
最佳實(shí)踐
發(fā)布減負(fù)
圖8 發(fā)布平臺(tái)使用git-poison進(jìn)行卡點(diǎn)
引入git-poison后,在團(tuán)隊(duì)的發(fā)布流程中,發(fā)布平臺(tái)會(huì)調(diào)用git-poison自動(dòng)導(dǎo)入本次版本發(fā)布的“Bugfix列表”和“未修復(fù)Bug列表”,便于發(fā)布經(jīng)理評(píng)估該版本的質(zhì)量風(fēng)險(xiǎn),無(wú)需再口頭追個(gè)確認(rèn)。包括本次發(fā)布修復(fù)的問(wèn)題列表,以及是否有未解決的bug。
Before | After |
1.發(fā)布同學(xué)git log兩次發(fā)布之間所有的commit 2.發(fā)布同學(xué)篩選本模塊相關(guān)commit 3.拉群一一詢(xún)問(wèn)對(duì)應(yīng)patch owner | 1.發(fā)布平臺(tái)自動(dòng)調(diào)用git-poison導(dǎo)入未修復(fù)bug, 發(fā)布經(jīng)理評(píng)估發(fā)布風(fēng)險(xiǎn) |
風(fēng)險(xiǎn)觀(guān)測(cè)
圖9 git-poison 聯(lián)動(dòng)線(xiàn)上風(fēng)險(xiǎn)展示
運(yùn)維平臺(tái)可以集成git-poison來(lái)檢查線(xiàn)上部署的服務(wù)版本是否存在中毒情況。線(xiàn)上風(fēng)險(xiǎn)一目了然。尤其是發(fā)現(xiàn)一個(gè)新bug后,值班同學(xué)可以立即投毒,并通過(guò)該頁(yè)面獲取該bug影響的范圍。
Before | After |
1.值班同學(xué)發(fā)現(xiàn)bug 2.值班同學(xué)去代碼倉(cāng)庫(kù)查找引入bug的commit對(duì)應(yīng)時(shí)間 3.獲取線(xiàn)上所有模板找到對(duì)應(yīng)的build版本 4.人肉排查該bug是否在對(duì)應(yīng)版本中 | 1.值班同學(xué)發(fā)現(xiàn)bug 2.使用git-poison進(jìn)行投毒查看影響范圍 |
結(jié)語(yǔ)
目前git-poison已經(jīng)在公司內(nèi)部開(kāi)源,團(tuán)隊(duì)已經(jīng)實(shí)現(xiàn)、使用并集成到發(fā)布平臺(tái)管理Bug一年多。開(kāi)發(fā)同學(xué)本地使用順暢,學(xué)習(xí)成本低,發(fā)布流程中多次有效阻塞帶bug的版本,并為定位bug影響范圍提供極大便利。
都說(shuō)寫(xiě)代碼容易,修bug難。在一個(gè)多人協(xié)作大項(xiàng)目中,修完bug還能保證不重復(fù)翻車(chē)就是難上加難。有了git-poison,相信事情會(huì)變的easy and simple。最后希望我們關(guān)于 git-poison 的實(shí)現(xiàn)邏輯可以分享給更多人。
阿里云開(kāi)發(fā)者社區(qū),千萬(wàn)開(kāi)發(fā)者的選擇。百萬(wàn)精品技術(shù)內(nèi)容、千節(jié)免費(fèi)系統(tǒng)課程、豐富的體驗(yàn)場(chǎng)景、活躍的社群活動(dòng)、行業(yè)專(zhuān)家分享交流,盡在:
https://developer.aliyun.com/?utm_content=g_1000371671
版權(quán)聲明:本文內(nèi)容由互聯(lián)網(wǎng)用戶(hù)自發(fā)貢獻(xiàn),該文觀(guān)點(diǎn)僅代表作者本人。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如發(fā)現(xiàn)本站有涉嫌抄襲侵權(quán)/違法違規(guī)的內(nèi)容, 請(qǐng)發(fā)送郵件至 舉報(bào),一經(jīng)查實(shí),本站將立刻刪除。