前面幾節(jié)課程中,我們已經(jīng)對常見的互聯(lián)網(wǎng)技術(shù),代碼編寫規(guī)范有了一定的學習和了解。這些技術(shù)以及規(guī)范在我們?nèi)粘5拈_發(fā)中都是經(jīng)常被使用到的。
這些技術(shù)的學習最終都是以應用為目標的,即需要把這些技術(shù)通過coding、軟件系統(tǒng)的組合(資源、服務(wù))等實現(xiàn)方式最終應用到線上環(huán)境當中。
對于小規(guī)模的開發(fā)團隊,因服務(wù)規(guī)模比較小,服務(wù)的部署可能是很簡單的——手動部署代碼成本也可控。但對于數(shù)十人上百人的開發(fā)團隊,大規(guī)模的分布式系統(tǒng)來說,原來簡單的方式就難以運轉(zhuǎn)了。我們急需一套符合軟件工程原理的流程體系,來保證我們研發(fā)效率、上線服務(wù)質(zhì)量。
今天我將結(jié)合微博平臺目前的上線流程以及個人的一些體會,來介紹一下研發(fā)上線流程體系。
培訓大綱:
對于一個剛進入公司的新同學,肯定有好多問題:
作為一個工程師,日常工作內(nèi)容都包括哪些呢?我是否只要寫代碼就可以了?
日常工作中,都需要與哪些同事打交道呢?
作為一個系統(tǒng)研發(fā)工程師,我對日常工作的一個總結(jié)如下:
主線任務(wù):完成需求開發(fā),推進上線
業(yè)務(wù)需求:完成各個業(yè)務(wù)部門產(chǎn)品需求
改造需求:來源于部門內(nèi)部技術(shù)方案、整體架構(gòu)升級、改造需求
支線任務(wù):提供其他的技術(shù)支持
線上系統(tǒng)問題跟蹤
產(chǎn)品數(shù)據(jù)分析支持
我們可以看到,一個工程師日常最主要的任務(wù)即是完成各類需求研發(fā)工作。這部分的工作實際上包括兩方面的內(nèi)容:
(1)功能研發(fā),也即通常所說的寫代碼
(2)推動上線部署
上線指的是將工程師開發(fā)的功能推動到線上生產(chǎn)環(huán)境中,為系統(tǒng)面向的用戶所使用。
在一些中小企業(yè)中,因面向的用戶總量不大,所需的服務(wù)器也無需太大,上線的過程可能會比較簡單——開發(fā)工程師完成代碼的編寫后,編譯,測試,手動部署可發(fā)布包到服務(wù)器上重啟即可。
但在大型的互聯(lián)網(wǎng)環(huán)境中,上述簡單的做法面臨著很多問題:
(1)分布式系統(tǒng)環(huán)境復雜,上線所涉及到的讀寫順序、操作流程更復雜
(2)同一個系統(tǒng)可能由多個工程師維護,代碼的變更涉及到多個功能、多個團隊
(3)系統(tǒng)代碼總量大,生命周期長,每一次的變更都有可能帶來潛在bug以及嚴重的故障
微博平臺歷史上也曾發(fā)生過多次故障。通過對故障的分析和總結(jié),我們發(fā)現(xiàn)約80%的故障都來源于系統(tǒng)變更。即每次上線變更其實都是隱含著很大的風險性的。
但是,作為互聯(lián)網(wǎng)工程師,我們并不可能因為上線變更所可能帶來的風險,就不進行新功能的研發(fā),停止不前。相反,我們根據(jù)軟件工程的開發(fā)流程原理以及業(yè)界的一些成熟的經(jīng)驗,結(jié)合我們的業(yè)務(wù)特點,以及自身歷史上發(fā)生過的幾次故障的經(jīng)驗,總結(jié)設(shè)計出了我們自己的一套的開發(fā)、上線流程??偟膩碚f,我們期望能夠:
(1)按時、高質(zhì)量交付需求、功能實現(xiàn)到生產(chǎn)環(huán)境
(2)研發(fā)過程明確清晰,每一步都是經(jīng)過充分review的
(3)上線過程步驟明確,較少運維誤操作
(4)出事可操作,always have plan B,即使出問題了,我們也可以快速恢復
(5)對研發(fā)效率的影響盡可能小
我們的研發(fā)上線流程由多個步驟組成,需要一步一步完成。對于我們的研發(fā)工程師來說,他需要關(guān)注每一步的:
(1)該步的檢查內(nèi)容
(2)需要提供的明確的產(chǎn)出物
(3)該步相應的審查人員
如圖1所示為研發(fā)上線流程的一個示意圖:
圖1 研發(fā)上線流程示意圖
從圖1中可以看到,整個研發(fā)流程由多個步驟組成,每個步驟都涉及到一個或多個人員。
因本節(jié)課更多的關(guān)注在上線部分的推動上,所以我們將從開發(fā)完成后開始詳細介紹:
即代碼評審,意指待交付的代碼經(jīng)過除開發(fā)工程師以外的人員進行評審檢查。
Code review的意義在于:
(1)幫助梳理邏輯,從而發(fā)現(xiàn)更好的實現(xiàn)方式
(2)幫助規(guī)范代碼,保證線上代碼的規(guī)范、質(zhì)量
(3)減少因開發(fā)人員個人經(jīng)驗、疏忽所可能帶來的bug
開發(fā)人員在提交codereview時候需要明確寫出相關(guān)代碼變更的需求來源、實現(xiàn)方案以及其他的能夠幫助評審人員快速了解這次變更內(nèi)容的文檔、資料。
當然code review本身也是需要一定的規(guī)范制度的:
明確reivew點。reviewer需要從多個層次進行reivew:代碼本身質(zhì)量(編碼風格,防御性編程等),代碼功能邏輯實現(xiàn),現(xiàn)有系統(tǒng)的影響(侵入、耦合、數(shù)據(jù)兼容性等)。需要避免單一角度review。對于上述的每一個層次的review,也需要有更細致的review點。
為了保證待發(fā)布代碼的質(zhì)量,我們在實際的工作中,會將測試交由單獨的測試部門同事負責檢測。測試的方式和手段也根據(jù)帶發(fā)布的變更不同而不同??偟膩碚f,對于日常功能變更,只需進行新功能測試已經(jīng)原有功能回歸即可。對于系統(tǒng)架構(gòu)級變更,則會通過壓測等衡量系統(tǒng)的負載情況。
對于功能測試來說,測試是對某個特性分支進行測試的,即對每個測試提案單獨測試。這樣做的目的是避免待上線功能相互影響,提高測試效率。
引入測試環(huán)節(jié)的意義在于:
由測試部門提供專業(yè)、全面的測試,從而保證測試的覆蓋度,以及測試的準確度
上線申請以及匯總:
上線申請值得是在代碼完成了cr以及通過了測試部門的檢驗后,需要向上級主管以及部門上線總調(diào)度人發(fā)送上線申請通知。
上線申請內(nèi)容主要包括本次上線變更內(nèi)容,代碼涉及的功能模塊,設(shè)計方案,需要上線的服務(wù)器集群,回滾方案等。開發(fā)人員需要明確提供上述的各類信息,以幫助上級主管、總調(diào)度人知悉本次上線功能以及可能造成的影響。
Code review以及測試更多的關(guān)注在代碼本身的質(zhì)量上,而業(yè)務(wù)主管的關(guān)注點更多的在于上線方案、變更可能造成的服務(wù)的影響點等問題上。
上線申請以及匯總的意義在于:
(1)上線功能的內(nèi)容經(jīng)過更高一級的review,從而保證上線服務(wù)的方案經(jīng)過更全面的review
(2)協(xié)調(diào)跨個人、跨團隊的上線。如上所述,我們每次上線都不是單獨某個人代碼變更,可能涉及到的團隊、功能是多個以上的。代碼的提交順序,模塊的打包順序,回滾方案等,都需要經(jīng)過統(tǒng)一的評估和協(xié)調(diào)。避免出現(xiàn)各自為政,代碼沖突無人負責等問題的出現(xiàn)。
(3)上線變更在部門范圍內(nèi)透明。如果出現(xiàn)某個功能問題,可以做到更大范圍的支持幫助。
當上線被業(yè)務(wù)主管以及上線總調(diào)度人通過后,研發(fā)人員可以將自己的特性分支合并到主分支上。并且交由運維同學打包部署。
對于線上代碼主分支的修改,我們是統(tǒng)一在上線調(diào)度人發(fā)出上線匯總郵件后,才進行。目的也是保證線上主干分支在任意時刻都是production級的。避免出現(xiàn)從主干分支獲取代碼后,出現(xiàn)不可知bug。
當研發(fā)人員將代碼提交完成后,由運維同學負責打出可發(fā)布包(docker鏡像)。
運維使用沒有線上真實請求流量的線上機器,部署包含新代碼的發(fā)布包,完成操作后由測試同學負責在該環(huán)境上執(zhí)行測試用例。
在前面的課程中也已經(jīng)提到了,在線上系統(tǒng)中,應用服務(wù)是由web服務(wù)器集群來提供服務(wù)的,同時由nginx來提供主要的負載均衡以及健康管理。
如圖2所示,線上nginx服務(wù)器會定時的向它所維護的web服務(wù)器發(fā)起健康探測請求,當實際的web服務(wù)器返回200響應時,則nginx認為該web服務(wù)器正常工作;相反,如果web服務(wù)器返回的是503響應時,則nginx認為該web服務(wù)器無法正常提供服務(wù),nginx將會把該web服務(wù)器從服務(wù)列表中摘除,后續(xù)請求將不會打到該web服務(wù)器上。
利用這個特性,我們可以將線上服務(wù)器從線上環(huán)境中摘除,即讓該服務(wù)器沒有線上請求。運維同學將部署新的代碼,重啟tomcat服務(wù)進程。啟動成功后,由測試對其進行功能測試,包括本次上線的所有的功能的測試,以及原測試用例的回歸。
預覽驗證的意義在于:
(1)使用線上服務(wù)器環(huán)境配置進行測試,所用數(shù)據(jù)都是真實的線上數(shù)據(jù),避免測試環(huán)境不一造成的bug遺漏
(2)合并后代碼的測試,避免合并代碼過程中造成的沖突修改引入不可知bug
預覽測試通過后,運維同學會將線上流量重新導到預覽機器上。此時,預覽機器部署的新代碼、配置,將經(jīng)受線上真實流量的檢驗。
線上流量是最好的檢驗環(huán)境。qa受限于測試用例覆蓋度的影響,可能無法做到所有代碼分支都檢測到,所以我們在線上服務(wù)器中引入真實流量用以檢驗代碼的功能的正確性以及對原有服務(wù)是否有明顯的影響。
我們通常通過對訪問日志統(tǒng)計、錯誤日志以及監(jiān)控系統(tǒng)的觀察來判斷變更是否符合要求。
完成上述的上線步驟后,運維可以通過發(fā)布系統(tǒng),將待發(fā)布的代碼推送到所有線上應用服務(wù)器上,完成本次系統(tǒng)的變更操作。
在推送的過程中,由于啟動服務(wù)進程本身需要一定的時間,所以運維發(fā)布系統(tǒng)會按一定的步長進行操作,即,將線上機器分批重啟,一批完成變更后,再進行另外一批。
得益于目前微博平臺的雙機房架構(gòu),我們在核心服務(wù)的上線是按機房進行上線的。即先上tc機房服務(wù),完成整個機房的變更后,由測試在tc的線上環(huán)境中進行測試用例回歸。通過后,再進行yf機房的上線。采取這樣的分機房上線的意義在于,如果tc發(fā)生問題,我們可以迅速的將流量導流到y(tǒng)f中,避免服務(wù)完全不可用。
故障是無法被避免的,無論我們的code review做的多細致,測試覆蓋的多全面,上線流程的審查多么嚴格,最終在變更的過程中依然可能會有因疏漏、bug導致的故障。
如果代碼中有預留相應的防御性措施,如開關(guān)等,那么可以通過采取相應的措施進行規(guī)避。
對于無法通過防御性編程進行錯誤恢復的變更,我們則需要進行回滾。即將線上代碼回滾到上一個穩(wěn)定版本中,取消變更。
在大型分布系統(tǒng)中,回滾也不是一件簡單的事情。即在很多時候,單純的回退代碼可能引入更為嚴重的問題:
(1)上線過程中寫入的數(shù)據(jù)無法做到向前兼容,回退代碼,會造成這部分數(shù)據(jù)丟失,甚至影響系統(tǒng)功能。
(2)代碼、配置回滾順序。系統(tǒng)采用了代碼、配置分離的管理策略。代碼的回滾可能依賴于配置的先回滾,單純回滾代碼可能會造成服務(wù)無法啟動的問題。
(3)隊列機、前端應用服務(wù)器回退順序。在線上系統(tǒng)中,我們采用前端應用服務(wù)器加隊列服務(wù)器的架構(gòu),即由隊列服務(wù)負責對資源進行更新,前端服務(wù)器只對資源進行下行獲取。當涉及到資源的上線回退的時候,資源的讀寫順序回退的錯亂可能會造成線上數(shù)據(jù)不一致。
圖3 異步消息處理架構(gòu)
所以我們在上線申請過程中,就需要明確回退步驟,包括:
(1)代碼配置回退順序
(2)前端機、處理機回退順序
(3)數(shù)據(jù)盡量做到向前兼容,無法向前兼容的需要明確指出
當線上真的發(fā)生了問題時,我們將馬上按照上線定好的回滾方案進行代碼、配置回滾。從而保證線上服務(wù)穩(wěn)定。?
本文主要結(jié)合微博平臺的開發(fā)、上線流程進行說明。如文中所說的,上線是一件具有風險的操作,每次新加入的功能點、改造變更,都可能給線上系統(tǒng)引入不可知的問題與故障。為了盡量減少類似風險,以及在類似問題出現(xiàn)后,可以快速的進行恢復,我們根據(jù)自身的業(yè)務(wù)特點總結(jié)設(shè)計出了一套研發(fā)上線流程。
引入流程并不是為了限制研發(fā)人員的研發(fā)效率,而是希望借助對每個流程環(huán)節(jié)的把控,從而保證我們每次變革的質(zhì)量,盡量減少bug、故障的發(fā)生。
當然,我們也不認為我們的流程能夠完全將故障排除。借助流程中的上線前梳理、代碼的防御性編程,回滾方案的準備等措施,以及上線后的監(jiān)控、發(fā)布系統(tǒng)的調(diào)度等措施來做到出事可干預,有問題可以快速回滾,從而減少故障對線上服務(wù)的影響。
?? ? 目前我們也在積極的推動持續(xù)集成、微服務(wù)、docker化,希望借助于這些新的技術(shù)來提升我們開發(fā)、上線的效率,本文因篇幅所限雖未就這些方面進行展開描述,但希望各位關(guān)注@微博平臺架構(gòu) 后續(xù)的微博、課程分享、討論。如果你有好的資料和建議,也可以隨時反饋給我們。
------------------新兵訓練營簡介------------------
微博平臺新兵訓練營活動是微博平臺內(nèi)部組織的針對新入職同學的團隊融入培訓課程,目標是團隊融入,包括人的融入,氛圍融入,技術(shù)融入。當前已經(jīng)進行4期活動,很多學員迅速成長為平臺技術(shù)骨干。具體課程包括《環(huán)境與工具》《分布式緩存介紹》《海量數(shù)據(jù)存儲基礎(chǔ)》《平臺RPC框架介紹》《平臺Web框架》《編寫優(yōu)雅代碼》《一次服務(wù)上線》《Feed架構(gòu)介紹》《unread架構(gòu)介紹》。微博平臺是非常注重團隊成員融入與成長的團隊,在這里有人幫你融入,有人和你一起成長,也歡迎小伙伴們加入微博平臺,歡迎私信咨詢
------------------講師簡介------------------
? ? ?賴佳?。ㄎ⒉╆欠Q:@LierD?),2013年7月畢業(yè)于哈爾濱工業(yè)大學后,加入新浪微博工作至今,擔任系統(tǒng)研發(fā)工程師。曾先后參與微博Feed流優(yōu)化、后端服務(wù)穩(wěn)定性建設(shè)等項目。關(guān)注jvm調(diào)優(yōu),微服務(wù),分布式存儲系統(tǒng)。微博平臺新兵訓練營二期學員.
業(yè)余愛好三國殺,dota,喜歡自己做飯下廚希望能在微博的平臺上認識到更多優(yōu)秀的小伙伴,一起交流,一起成長
更多建議: