大规模开发团队如何实现DevOps转型? 来自微软全球开发平台工程团队的实践经验
微軟全球開發(fā)平臺工程團(tuán)隊從敏捷到DevOps的轉(zhuǎn)型
2013年11月13日,我們宣布了Visual Studio2013,以及微軟研發(fā)云Visual Studio Online (VSO)的正式商用。緊接著我們經(jīng)歷了一次長達(dá)七小時的服務(wù)中斷。我們的服務(wù)運行在一個“彈性擴(kuò)展單元”中,為大約一百萬用戶提供服務(wù)。當(dāng)時恰逢峰值流量時間段,歐洲和美國東西海岸的用戶均已上線,在市場部門對外公布正式商用的同時,我們正在通過“功能開關(guān)”啟用各種本被隱藏的新功能。隨后發(fā)現(xiàn)負(fù)責(zé)服務(wù)間通信的IP端口,這個重要的網(wǎng)絡(luò)層組件未能如期生成我們需要的遙測數(shù)據(jù)。當(dāng)時因為新功能發(fā)布,已經(jīng)產(chǎn)生了大量請求。從技術(shù)的角度來看,這造成了一個很尷尬的情況,如圖1所示。當(dāng)時的細(xì)節(jié)情況可以參閱這里。[i]
圖1:VS 2013的發(fā)布因為VS Online服務(wù)一系列尷尬的中斷而面臨窘境。
從市場的角度來看,本次發(fā)布活動無疑是一個巨大的成功。VS Online服務(wù)借助這一轉(zhuǎn)折點,成功地實現(xiàn)了兩位數(shù)的用戶數(shù)月增量。(增長的趨勢還在繼續(xù),隨后一年里,百萬級別的用戶數(shù)順利翻倍。)
功能與后端保障之間的權(quán)衡
那段時間里,VSO只有一個托管在芝加哥數(shù)據(jù)中心內(nèi)的彈性擴(kuò)展單元。我們很清楚,需要通過多個單獨部署的彈性擴(kuò)展單元進(jìn)行橫向擴(kuò)展,但我們總是更重視與功能有關(guān)的工作,忽略了使用多個彈性擴(kuò)展單元為網(wǎng)站提供更周全的保障這件事情。發(fā)布會上遭遇的情況讓我們改變了自己的想法。相關(guān)團(tuán)隊決定將本已計劃好的功能改進(jìn)工作延期,全力解決后端的保障工作。我們需要通過某種方式對VSO的后續(xù)更新進(jìn)行“金絲雀部署“。原本使用的芝加哥彈性擴(kuò)展單元(我們稱之為SU1)保持不變,但我們打算在該彈性擴(kuò)展單元之前增加另一個單元,新增的單元被命名為SU0。
在這一過程中,首先我們會將所有沖刺(sprint)版本部署至圣安東尼奧?(Scale Unit 0),在這個位置運行一段時間。如果感覺一切正常,才會將其滾動部署至芝加哥的單元?(Scale Unit 1),如圖2所示。當(dāng)然,如果SU0遇到問題,還可以修復(fù)問題并重新啟動新一輪的部署。后來我們又在這個序列中加入了更多Azure數(shù)據(jù)中心。到2014年秋季,我們增加了阿姆斯特丹作為第五個數(shù)據(jù)中心。隨著業(yè)務(wù)繼續(xù)擴(kuò)展至全球更多地區(qū),很快我們還將加入澳大利亞。在以上過程中,我們都在使用Visual Studio Release Management來處理部署流程和自動化滾動更新等操作,每一個沖刺版本都是這樣部署的。
?
??圖2:2013年11月之后,VSO從原本的一個數(shù)據(jù)中心擴(kuò)展至多中心,借此實現(xiàn)“金絲雀”部署和全球落地。
對于線上環(huán)境服務(wù)質(zhì)量的重視立刻獲得了立竿見影的效果。從2014年4月服務(wù)月度點評(圖3)中可以看到,2013年11月共出現(xiàn)了43個線上問題(LSI),六個月后驟降至7個,其中僅兩個來自正式發(fā)布(非預(yù)覽)的服務(wù)。我們還在持續(xù)完善自己的DevOps實踐和運維實踐,注重保持線上環(huán)境的健康狀況,不過接下來還有很長的路要走。
圖3:到2014年4月,VSO僅觸發(fā)了7個LSI,六個月前這一數(shù)據(jù)還是43個。在這七個LSI中,只有兩個是已經(jīng)正式發(fā)布的服務(wù)造成的。
我們?nèi)绾螐拿艚蒉D(zhuǎn)型為DevOps
七年來,微軟全球開發(fā)平臺工程團(tuán)隊?(Developer Division, DevDiv)一直在擁抱敏捷。借助切實可行的工程實踐,我們從XP時代逐漸積累的技術(shù)債減少了15倍。我們?yōu)椴块T內(nèi)部負(fù)責(zé)不同方向的團(tuán)隊和產(chǎn)品負(fù)責(zé)人提供Scrum培訓(xùn),并將為客戶提供價值作為一切的核心。在發(fā)布Visual Studio 2010時,該產(chǎn)品線獲得了前所未見的客戶認(rèn)可。[ii]
發(fā)布VS2010之后,我們很確定是時候?qū)?/span>Team Foundation Server轉(zhuǎn)型為軟件即服務(wù)?(SaaS)的研發(fā)云產(chǎn)品了。該服務(wù)的SaaS研發(fā)云最早被命名為?Visual Studio Online (VSO),現(xiàn)在已經(jīng)改名為Visual Studio Team Services(VSTS)?研發(fā)云,托管于Microsoft Azure (不過在我們工程團(tuán)隊內(nèi)部還是習(xí)慣使用VSO來稱呼這個產(chǎn)品)。為了繼續(xù)延續(xù)之前的成功,我們需要開始采用更多的DevOps實踐,這也意味著我們需要將實踐從敏捷轉(zhuǎn)型為DevOps。這兩者有何差別?
DevOps文化的特點之一在于需要從使用中學(xué)習(xí)經(jīng)驗。對于敏捷,有一種心照不宣的假設(shè),認(rèn)為產(chǎn)品負(fù)責(zé)人是無所不知的,能夠正確提出產(chǎn)品的規(guī)劃和新的需求列表。與之相反,在運行某種高度可靠的服務(wù)時,你可以用近乎實時的方式觀察用戶是如何使用不同功能的。你可以更頻繁地發(fā)布新版,通過實驗進(jìn)一步完善,衡量并詢問客戶對不同改變的看法。這一過程中所收集的數(shù)據(jù)將成為后續(xù)一系列改進(jìn)的依據(jù)。通過這種方式,DevOps產(chǎn)品的需求列表實際上是一系列假設(shè),最終會變?yōu)檐浖\行過程中所做的實驗,并可促成持續(xù)不斷的反饋循環(huán)。
如圖4所示,從敏捷中催生出的DevOps基于四大趨勢:
圖4:這四大趨勢推動了DevOps的演變。
與很多“生于云端”的公司不同,我們最開始并沒有SaaS產(chǎn)品,客戶主要在PC端本地環(huán)境中使用我們的軟件(Team Foundation Server最初發(fā)布于2005年,現(xiàn)已發(fā)布了2017版)。在開發(fā)VS Online,也就是現(xiàn)在的VSTS研發(fā)云時,我們決定為SaaS和“盒裝”版本的產(chǎn)品維護(hù)同一個代碼庫,但采取云為先的開發(fā)策略。工程師在推送代碼后將觸發(fā)持續(xù)集成流程。當(dāng)為期三周的沖刺結(jié)束后,我們會發(fā)布到云端,進(jìn)行4-5個沖刺后,會為“盒裝”產(chǎn)品發(fā)布一個季度更新,過程如圖5所示。
圖5:我們?yōu)?/span>VSTS研發(fā)云(SaaS產(chǎn)品)和TFS(本地運行產(chǎn)品)使用了同一個代碼庫。每三周,我們會將新功能部署至VSTS研發(fā)云。每季度,這些更新會滾動發(fā)布至TFS。在發(fā)布重大TFS更新,如2015版時,則會基于當(dāng)時VSTS研發(fā)云的版本進(jìn)行。
暴露控制
在開發(fā)服務(wù)的過程中,高頻率發(fā)布會讓我們獲益匪淺。在我們的工作中,我們會在為期三周的沖刺結(jié)束后發(fā)布。借此我們可以更及時地將工作成果展現(xiàn)給用戶,但我們需要對暴露的時機(jī)進(jìn)行一定的控制。這方面我們遇到了一些問題:
l?如何處理需要多次沖刺才能完成的功能?
l?如果明確知道某個功能隨后需要改動,又該如何針對不同功能進(jìn)行實驗以便了解使用情況和用戶反饋?
l?如何通過“灰度上線”在做好對外發(fā)布和公開推廣之前引入新的服務(wù)或功能?
對于所有這些問題,我們選擇了功能開關(guān)這種模式。功能開關(guān)是一種控制機(jī)制,決定了要將何種功能暴露給哪些用戶或用戶組。隨著團(tuán)隊針對新功能開展工作,我們可以通過功能開關(guān)服務(wù)注冊一個開關(guān),這種開關(guān)默認(rèn)處于關(guān)閉狀態(tài)。在準(zhǔn)備好讓某些用戶嘗試新的功能后,即可為這些用戶在生產(chǎn)環(huán)境中打開對應(yīng)的開關(guān),并根據(jù)需要決定何時關(guān)閉。如果要改動對應(yīng)的功能,無需重新部署即可關(guān)閉這個開關(guān),停止該功能的對外暴露。
通過這種方式實現(xiàn)漸進(jìn)式的暴露控制,功能開關(guān)還提供了一種供我們在生產(chǎn)環(huán)境中進(jìn)行測試的好方法。通常一開始我們會將新功能暴露給內(nèi)部員工,隨后暴露給早期用戶,隨后逐步暴露給更廣泛的客戶群體。通過對性能和使用情況進(jìn)行監(jiān)控,可以確保新的服務(wù)組件在大規(guī)模環(huán)境中可以正常無障礙運行。
代碼速率和分支
當(dāng)我們于2008年首次采用敏捷開發(fā)時,我們認(rèn)為可以通過適當(dāng)?shù)馁|(zhì)量門禁?(Quality gate)?和代碼分支結(jié)構(gòu)開發(fā)出更高質(zhì)量的代碼。早期的開發(fā)工作會使用一些異常復(fù)雜的代碼分支結(jié)構(gòu),只能接受按照嚴(yán)格定義編寫的代碼,通過封閉簽入(gated checkin)機(jī)制,確保新提交的代碼必須和主干代碼完成預(yù)合并,并經(jīng)過構(gòu)建策略的檢查后才能真正進(jìn)入配置庫。
這種代碼分支結(jié)構(gòu)造成了一種始料未及的后果:很多時候我們需要花費數(shù)周甚至數(shù)月的時間才能把葉子分支上的代碼逐層合并進(jìn)入主干。而分支中的代碼將長時間處于未合并狀態(tài),這又會為合并工作造成大量遺留債務(wù)。當(dāng)工作成果已經(jīng)準(zhǔn)備好進(jìn)行合并后,主干可能已經(jīng)進(jìn)行了大幅度的改動,導(dǎo)致出現(xiàn)合并沖突,進(jìn)而需要花費大量人力物力進(jìn)行協(xié)調(diào)。
2010年,我們采取的第一個措施是將代碼分支結(jié)構(gòu)大幅“壓平”,僅保留很少的分支,并且保留的分支大部分也是臨時的。我們明確了目標(biāo),要優(yōu)化代碼流動速度,換句話說,就是將代碼簽入和可被其他人獲取的間隔時間降至最低。
隨后我們使用Git打造了一個分布式版本控制系統(tǒng),該系統(tǒng)目前也已被VSTS研發(fā)云和TFS所支持。我們的大部分客戶和同事依然在使用集中化的版本控制系統(tǒng),因此VSTS研發(fā)云和TFS可以同時支持這兩種模式。Git的優(yōu)勢在于可以實現(xiàn)非常輕量級的臨時分支。我們可以為工作項創(chuàng)建特性分支,并在將變更合并到代碼主干后進(jìn)行立即清理掉該特性分支。
提交后的所有代碼位于Master(主干)中,同時Pull-request工作流結(jié)合了代碼審閱和質(zhì)量門禁功能。借助這些能力,代碼合并工作已經(jīng)可以通過簡單的小批次操作持續(xù)進(jìn)行,每個人隨時都可以看到最新的代碼。
這種流程可以在短時間內(nèi)對不同開發(fā)者的工作進(jìn)行隔離,隨后以持續(xù)的方式集成在一起。這種臨時分支還降低了后期維護(hù)的開銷,可在不需要時徹底刪除。
Agile on?Steroids
我們依然在遵循Scrum的原則,但為了促進(jìn)交流和跨地域擴(kuò)展,只保留了其中的精髓。例如我們工作主要以功能小組?(Feature crew)?為單位,這類似于Scrum中團(tuán)隊的概念,但產(chǎn)品負(fù)責(zé)人需要加入團(tuán)隊并參加所有日常工作。產(chǎn)品負(fù)責(zé)人和工程主管聯(lián)手代表整個團(tuán)隊。
我們還運用了團(tuán)隊自治和組織整合?(Organizational alignment)?的原則,借此功能小組中產(chǎn)生了新的變化。團(tuán)隊往往涉及多個領(lǐng)域,我們通過整合開發(fā)人員和測試人員的職業(yè)晉升路徑將這兩個角色統(tǒng)一成了一個工程角色(此舉大幅提升了士氣)。
所有團(tuán)隊都是內(nèi)聚的。每個小組有8-12名工程師,我們會盡可能確保他們至少可以共同工作12–18個月,很多團(tuán)隊的合作時間甚至更長。如果因為工作原因需要調(diào)整,我們會建立第二個小組來處理積壓的工作,而不會讓工程師在不同小組間來回更替。每個功能小組都有自己的團(tuán)隊辦公室,如圖6所示。這樣的辦公室并不是那種大面積開放式空間,而是一個專屬的房間,可供大家針對同一個領(lǐng)域開展工作并自如地交流。團(tuán)隊辦公室旁邊還為可能的突發(fā)情況準(zhǔn)備了小的“焦點辦公室?(Focus Room)”,這種辦公室中,我們也非常鼓勵自由的交流。到了每日站立會議時間時,大家都會站起來暢所欲言。
圖6:在同一個團(tuán)隊辦公室中干活的功能小組成員。
根據(jù)經(jīng)驗,我們最終選擇以三周為一個沖刺周期。事實證明對于我們這種需要全球協(xié)作的任務(wù),很難在更短的時間里為客戶提供足夠多的價值,而如果選擇更長的周期,則會影響新功能的發(fā)布速度。微軟內(nèi)部一些部門以兩周為一個沖刺周期,但也有一些部門甚至?xí)刻於啻吾槍π鹿ぷ鞒晒归_各種實驗,不會受到?jīng)_刺的約束。
從概念上來看,“完工”的定義其實很好理解。構(gòu)建,運行,這樣就行了。當(dāng)一次沖刺結(jié)束后,你的代碼會正式部署給數(shù)百萬用戶,如果代碼中存在任何問題,你(以及其他每個人)立刻就能知道,并可立即開始修復(fù)問題根源。
我們會輪流擔(dān)任ScrumMaster?這個角色,這樣每個人都有機(jī)會體驗Scrum Master的管理責(zé)任。在對外交流方面,我們會讓沖刺的儀式?(Ceremony)?盡可能簡潔。每次沖刺開始時,隊員從產(chǎn)品積壓工作列表?(Product Backlog)中領(lǐng)取任務(wù),并通過一封篇幅不超過一頁的郵件就自己的沖刺計劃進(jìn)行描述,郵件中需要添加指向VSTS研發(fā)云中產(chǎn)品積壓工作列表內(nèi)容(PBI)的超級鏈接。大家可以通過回復(fù)這封郵件的方式共同對沖刺進(jìn)行審閱,同時,團(tuán)隊還會提供一個大約三分鐘左右時長的視頻。視頻中包含演示,會從客戶的角度介紹通過本次沖刺所能實現(xiàn)的目的。
我們還會確保計劃盡可能簡單。通常來說,會針對未來18個月的工作制定愿景,并朝著這個方向努力。愿景可以通過多種形式體現(xiàn),例如技術(shù)尖峰?(Spike)、故事板?(Storyboard)、概念視頻,以及概括性文檔。我們以每6個月為一季,“春季”或“秋季”,在這段時間內(nèi)我們會圍繞整個團(tuán)隊的承諾和依賴關(guān)系堅持不懈地完成工作。每三次沖刺后,功能小組的領(lǐng)導(dǎo)者會聚在一起進(jìn)行一次“功能溝通會”,借此分享希望達(dá)到的優(yōu)先級,修正后續(xù)工作方向,與其他團(tuán)隊交流尋求新的目標(biāo)并確保所有團(tuán)隊保持一致。例如可以使用功能溝通會重新對網(wǎng)站工作和用戶可見的功能進(jìn)行劃分。
構(gòu)建—度量—學(xué)習(xí)
在經(jīng)典敏捷實踐中,由產(chǎn)品負(fù)責(zé)人對產(chǎn)品積壓工作項?(PBI)?進(jìn)行優(yōu)先級排序,大家會或多或少地將其視作一種需求。PBI?可能體現(xiàn)為用戶故事,形式可能非常簡單,但必須是確定無誤的。我們以前就是這樣工作的。
但現(xiàn)在不是了。為了遵循DevOps實踐,我們會將PBI視作“假設(shè)”。這些假設(shè)必須能轉(zhuǎn)化為實驗,借此獲得能夠支撐或減少實驗的證據(jù),隨后,我們還可以從這些證據(jù)中學(xué)到切實可行的經(jīng)驗。[iii]
進(jìn)行一個足夠好的實驗,要求有具備統(tǒng)計學(xué)意義的樣本,同時還有用于對照的控制組,此外還需要理解不同因素的影響結(jié)果。例如圖7中的這個例子,我們遇到了一個問題:VSTS研發(fā)云的新用戶并沒有立刻創(chuàng)建團(tuán)隊項目,而沒創(chuàng)建團(tuán)隊項目會導(dǎo)致用戶無法執(zhí)行其他絕大部分操作。圖7展示了在網(wǎng)頁上開始創(chuàng)建團(tuán)隊項目時的界面。
圖7:原本的方法需要執(zhí)行太多操作,并且很容易讓用戶分心,很多用戶希望能以更自然的操作來創(chuàng)建項目。
我們修改了Web端和IDE中的這部分體驗。圖8顯示了IDE中的新體驗,該體驗會鼓勵用戶通過兩個界面注冊VSTS研發(fā)云并建立項目。我們借助六個彈性擴(kuò)展單元中的兩個對這個新體驗進(jìn)行了實驗。
圖8:在兩個彈性擴(kuò)展單位中為IDE實現(xiàn)了更完善的項目創(chuàng)建體驗實驗。
這次IDE實驗的影響如圖9所示。新客戶創(chuàng)建團(tuán)隊項目的比例由3%增長至20%(增幅約七倍)!
圖9:IDE中的流程變動讓新用戶通過IDE創(chuàng)建項目的比例從3%增長至20%。
于此同時,我們還改進(jìn)了Web界面的注冊過程,也獲得了非常明顯的效果。圖10展示了Web注冊所做的改動。
圖10:Web注冊通過類似的簡化可以在第二個界面上直接建立項目。
我們統(tǒng)計了在注冊帳戶當(dāng)天就建立了團(tuán)隊項目的用戶比例。這一比例從原本的約18%增長至30%(約1.7倍),如圖11中從綠色過渡至黃色的柱狀條所示。雖然結(jié)果喜人,但其實這一結(jié)果與我們預(yù)期相差較遠(yuǎn),同時與IDE方面的所取得的大幅提升之間有很大的差距。
圖11:Web帳戶創(chuàng)建的結(jié)果由于兩個實驗出乎意料的相互干擾而被誤導(dǎo)。排除這些因素后,結(jié)果就很清楚了。
后續(xù)調(diào)查中發(fā)現(xiàn),我們其實還在同一時間進(jìn)行了另一個實驗。在這個實驗中,位于漏斗頂端很多不符合要求的用戶也被鼓勵注冊帳戶,但他們并未這樣做。這也證明了我們的控制組不夠完善,兩個實驗相互之間產(chǎn)生了干擾。在停止了用于加速創(chuàng)建帳戶的實驗后,項目創(chuàng)建比例激增至50%,如圖中綠色柱狀圖所示(增加2.8倍,比IDE中的效果還要好2.5倍)。
這個故事的寓意在于,實驗的執(zhí)行過程有好有壞,并不能總是很明顯地確定結(jié)果是否合理,是否可重現(xiàn),以及是否受到了妥善的控制。
為DevOps打造的工程系統(tǒng)
VSTS研發(fā)云是一種24x7x365可用的全球化服務(wù),提供了包含財務(wù)保障的99.9%高可靠性。但是要注意,99.9%的SLA并不是我們努力實現(xiàn)的目標(biāo),而是最低程度的保障,因為低于該標(biāo)準(zhǔn)我們就要給用戶退款。我們的目標(biāo)是做到100%的高可用和客戶滿意:不因為維護(hù)而停機(jī),無需全新安裝只需更新,整個過程完全自動化。這就要求所有服務(wù)必須相互解耦,具備明確的調(diào)用規(guī)則和清晰的版本控制。與很多客戶的系統(tǒng)類似,VSTS研發(fā)云也運行在Azure公有云上,整個基礎(chǔ)架構(gòu)都由Azure提供。
自動化部署
該服務(wù)的部署和網(wǎng)站可用性工程是由一個名為服務(wù)交付?(SD)?的小型團(tuán)隊管理的,該團(tuán)隊直接向工程團(tuán)隊負(fù)責(zé)。每次沖刺后的下一個周一,SD團(tuán)隊會開始進(jìn)行部署。部署過程可通過Visual Studio Release Management自動實現(xiàn),如圖12所示。我們會在工作時間內(nèi)進(jìn)行部署,這樣一旦遇到問題也可以更方便地進(jìn)行調(diào)查和補(bǔ)救。由于VSTS研發(fā)云中存儲了客戶數(shù)據(jù),而數(shù)據(jù)庫架構(gòu)經(jīng)常需要更新,因此無法進(jìn)行真正意義上的回滾,只能進(jìn)行前滾。滾動操作會自動從一個彈性擴(kuò)展單位延續(xù)到下一個彈性擴(kuò)展單元,首先從金絲雀彈性部署單元SU0開始。借助這種方式,我們可以循序漸進(jìn)地對功能暴露進(jìn)行控制,檢查運行狀況和用戶體驗,以便推進(jìn)下一步的部署。
圖12:VS Release Management控制著從一個彈性擴(kuò)展單位按順序向著下一個彈性擴(kuò)展單位進(jìn)行部署。
每個部署都從SU0開始,部署完成后維持運行幾小時,隨后繼續(xù)進(jìn)行下一單元部署。如果遇到問題,能在SU0順利解決是最理想的情況,我們會針對問題根源進(jìn)行修復(fù),隨后繼續(xù)部署。如果數(shù)據(jù)受損必須進(jìn)行災(zāi)難恢復(fù)(萬幸這種情況只出現(xiàn)過一次),我們也只會在SU0中針對自己的數(shù)據(jù),而非客戶的數(shù)據(jù)進(jìn)行恢復(fù)。
遙測
遙測機(jī)制可以說是VSTS研發(fā)云中最重要的代碼。如果服務(wù)本身有問題,監(jiān)控機(jī)制也必須保持可用狀態(tài)。如果服務(wù)遇到問題,監(jiān)控警報和儀表板需要能立刻匯報相應(yīng)的問題。圖13展示了一個服務(wù)運行狀況概述的示例。
圖13:這是組成VSTS研發(fā)云服務(wù)遙測功能的眾多頂級圖表之一。
VSTS研發(fā)云每個組件都經(jīng)過精心設(shè)計,能針對可用性、性能、使用情況,以及排錯提供360°視圖。遙測也遵循了類似原則。
我們寧愿做可能會沒有用的工作,也要盡可能收集一切信息。
我們會努力專注于各種切實可行的度量指標(biāo),而不是那些浮夸無用的指標(biāo)。
除了反饋本身,我們還會度量各種結(jié)果和比例,借此來確定所采取的各類措施的效果。
平均每天我們會收集60GB-150GB的遙測數(shù)據(jù)。雖然可以向下挖掘至特定客戶的相關(guān)信息,但按照我們的隱私策略,除非客戶選擇與我們分享,否則所有的數(shù)據(jù)都會匿名化處理。我們收集的部分?jǐn)?shù)據(jù)包括:
活動日志。我們會針對VSTS研發(fā)云服務(wù)收到的Web請求收集所有數(shù)據(jù)。借此可以追蹤每個命令的執(zhí)行耗時和次數(shù),進(jìn)而判斷特定調(diào)用或依賴服務(wù)是否變得緩慢或需要頻繁重試。
跟蹤記錄。任何問題相關(guān)的堆棧跟蹤(Stack Trace)信息都會被記錄,并用于對調(diào)用序列進(jìn)行調(diào)試。
作業(yè)歷史。作業(yè)是一種對跨越服務(wù)的活動進(jìn)行編排的工作流。
性能計數(shù)器。這些計數(shù)器與執(zhí)行性能排錯問題的計數(shù)器類似,可以追蹤系統(tǒng)資源運行狀況,VSTS研發(fā)云每天會生成約5千萬條事件。
Ping Mesh。這是一種對網(wǎng)絡(luò)基礎(chǔ)層進(jìn)行快速可視化的方法,借此可以保障全球網(wǎng)絡(luò)連接的可用性。
綜合事務(wù)。也叫“由外至內(nèi)的測試”,通過Global Service Monitoring運行,可從全球用戶的視角檢測運行狀況。
客戶用量。在用量方面我們會度量自己的“流量入口”、轉(zhuǎn)化漏斗、參與情況,以及首要客戶。
KPI指標(biāo)。這些是遙測系統(tǒng)通過計算匯總的指標(biāo),借此可判斷服務(wù)的商業(yè)健康度。
追蹤
最重要的一點,我們必須避免將任何事情當(dāng)成是理所當(dāng)然,每個人都接受“線上文化”的理念。換句話說,服務(wù)狀態(tài)永遠(yuǎn)被我們放在第一位。如果線上遇到了問題,那么所有人必須優(yōu)先加以處理,問題的檢測和補(bǔ)救是此時的頭等要務(wù)。我們的所有走廊里都安裝了實時儀表板,服務(wù)運轉(zhuǎn)好壞所有人都一目了然。
所有活動網(wǎng)站問題(LSI)?都會記錄到VSTS研發(fā)云中,進(jìn)而用于分析根源并每周審查。圖14展示了LSI的一個范例。
圖14:生產(chǎn)服務(wù)遇到的每個事件,包括補(bǔ)救根源問題的相關(guān)細(xì)節(jié)均會通過LSI進(jìn)行追蹤。
當(dāng)警報響起
DevOps的一個常見問題是:“誰帶著傳呼機(jī)?”在我們這里,成員遍布世界各地的服務(wù)交付?(SD)團(tuán)隊永遠(yuǎn)是24x7保障的第一道防線。如果需要將問題上報至開發(fā)團(tuán)隊,他們會按照功能小組所定義的指定負(fù)責(zé)人(DRI)?的工作時間安排進(jìn)行上報。我們對服務(wù)層面的預(yù)期為,DRI能在5分鐘(工作時間)或15分鐘(下班時間)里接手。
我們對“補(bǔ)救”的看法也很重要。我們的補(bǔ)救不是切換一個虛擬機(jī)那么簡單,而是要修復(fù)造成問題的根本原因。這種做法有點類似于豐田在工廠里安置的報警拉繩?(Andon cord),如果在流水線上發(fā)現(xiàn)殘次品,任何工人都里可以拉繩報警。[i]我們希望從來源位置修復(fù)代碼或配置問題,通過完善測試和發(fā)布流程預(yù)防相同問題再次發(fā)生。所有線上問題響應(yīng)的度量指標(biāo)都是以分鐘為單位來衡量的。
這方面我們?nèi)〉昧艘粋€巨大的成果,通過足夠精確的警報機(jī)制,可以在無需人工介入的情況下自動聯(lián)系DRI。為此我們建立了一個消除噪音和冗余警報,建立智能邊界的運行狀況模型,用它判斷真正需要采取措施的時機(jī),該模型如圖15所示。借此我們在2015年2月將警報精確度提高了40倍,所有P0和P1警報都能自動上報給負(fù)責(zé)人。
圖15:這個運行狀況模型可以自動消除重復(fù)的警報,并判斷問題根源可能在哪個功能領(lǐng)域中。
從用戶的體驗中學(xué)習(xí)
盡管為工作制造了不少困難,但我們在工程中的方方面面都在逐漸更貼近用戶體驗。例如計算出99.9%的服務(wù)級別協(xié)議?(SLA)所采用的方法就是一個很好的例子。
SLA本身并不是我們的目標(biāo)。我們的目標(biāo)是100%的滿意度。這意味著我們需要執(zhí)著于可能只占0.001%的異常情況。因為異常情況往往隱藏在平均情況中,為了讓SLA的計算更嚴(yán)謹(jǐn),我們陸續(xù)開發(fā)了三代算法。這三代算法的具體情況如圖16所示。最初我們使用了由外至內(nèi)的監(jiān)視(下圖中虛線所示)用來追蹤服務(wù)器的可用性。第二代算法主要關(guān)注相對所執(zhí)行命令的總數(shù),執(zhí)行緩慢或失敗的命令的相對數(shù)量,借此找出更普遍的異常情況所對應(yīng)的問題(下圖黃線和藍(lán)線)。隨著服務(wù)繼續(xù)完善,“分母”已經(jīng)排除了大部分不符合要求的客戶所對應(yīng)的情況。目前我們采取的計算方法是計算用戶所遇到的服務(wù)不可用的分鐘數(shù)在總使用分鐘數(shù)中所占的比重,用黑線代表。
圖16:這個LSI圖對比了三種計算SLA的方法。由外至內(nèi)的監(jiān)視沒發(fā)現(xiàn)任何問題,追蹤命令執(zhí)行結(jié)果的方法顯示有一小時運行緩慢,而真實用戶的監(jiān)視發(fā)現(xiàn)經(jīng)歷了三個小時的響應(yīng)延遲。
從上述四小時的統(tǒng)計可見,第一個(虛線)SLA顯示沒有任何問題。第二個(黑線)顯示問題持續(xù)一小時,第三個顯示性能低下持續(xù)三小時。實際上我們并不“需要”如此嚴(yán)格的度量,但還是這么做了。只為打造更優(yōu)秀的服務(wù)。
安全性
作為例行安全實踐的一部分,我們需要提供有保障的數(shù)據(jù)隱私、數(shù)據(jù)保護(hù)、服務(wù)可用性,以及服務(wù)安全性。過去,對于本地部署的軟件,為了構(gòu)建縱深防御機(jī)制預(yù)防安全問題,我們付諸了巨大的努力。很明顯,現(xiàn)在依然需要這樣做,此外我們還開始假設(shè)服務(wù)已經(jīng)被攻陷,并考慮該如何檢測這樣的入侵行為。[ii]
除了使用SU0進(jìn)行金絲雀部署,我們還可以通過這個數(shù)據(jù)中心進(jìn)行安全演練,這么做的目的與消防演練類似,是為了進(jìn)一步加固VSTS研發(fā)云服務(wù)。通過這樣的彈性擴(kuò)展單元進(jìn)行模擬攻擊,無需擔(dān)心可能會對付費客戶的服務(wù)造成任何影響。
新的開發(fā)模式
以往只開發(fā)本地部署的軟件時,我們會通過對工程系統(tǒng)和流程進(jìn)行優(yōu)化實現(xiàn)最小化的平均故障間隔時間。換句話說,我們會將軟件發(fā)布給客戶,如果隨后發(fā)現(xiàn)有錯誤需要糾正,修復(fù)成本是極為昂貴的,因此我們會盡可能提前采取一切措施發(fā)現(xiàn)可能存在的問題,盡量避免需要發(fā)布新的軟件版本。
DevOps徹底改變了這種做法。如果能通過“無痛”的重新部署將修復(fù)成本降至最低,那么此時的目標(biāo)將截然不同。周期時間、發(fā)現(xiàn)時間、補(bǔ)救時間,學(xué)習(xí)時間,所有這一切時間都需要降至最低。
這也催生出多種彈性設(shè)計模式。依賴項有可能發(fā)生故障,最有可能在流量峰值時期出現(xiàn)。因此服務(wù)必須能夠平穩(wěn)地降級,具備周全的重試策略,例如“斷路開關(guān)”就是如此,[iii]而且需要能通過類似混沌猴子?(Chaos monkey)?那樣的實踐進(jìn)行加固,這種方式是?Netflix?發(fā)明的。[iv]
災(zāi)難恢復(fù)計劃至關(guān)重要,而我們會在模擬攻擊的時候?qū)@些計劃進(jìn)行測試。無心之失或重大災(zāi)難隨時有可能發(fā)生,我們需要對此做好準(zhǔn)備。
開源
在我們轉(zhuǎn)型方法的過程中,越來越多地以用戶和貢獻(xiàn)者的身份加入到開源軟件?(OSS)?社區(qū)中。OSS工作流程的中的重點在于分享、復(fù)用和協(xié)作。OSS鼓勵提供可以單獨發(fā)布,松耦合的協(xié)作服務(wù)。
如果針對我們遇到的問題有現(xiàn)成的?OSS?解決方案,我們會直接使用,而不會“重新發(fā)明車輪”。如果我們開發(fā)的一些東西能夠讓更多人獲益,我們會分享給社區(qū)。對于創(chuàng)造出受歡迎組件的工程師,我們會給予獎勵,同時我們也鼓勵公司里的每個人直接利用獲得批準(zhǔn)可以使用的組件。任何工程師,都可以為公司里任何產(chǎn)品的改進(jìn)貢獻(xiàn)自己的力量。與此同時,在內(nèi)部,我們還會提供企業(yè)代碼監(jiān)管機(jī)制,并要求為產(chǎn)品提供更長的支持時間。
學(xué)習(xí)的平均時間
事件發(fā)生后,只有經(jīng)過調(diào)查并從中總結(jié)出經(jīng)驗教訓(xùn)才算徹底處理完成。我們會使用“5個Why”[v]從不同角度記錄下次該怎樣才能做得更好。如果出現(xiàn)影響到客戶的故障,Brian Harry會以責(zé)任高管的身份發(fā)布博客文章,解釋具體情況以及從中學(xué)到的經(jīng)驗。這個博客類似一種公共記錄和追責(zé)機(jī)制,促使我們不斷地精益求精。[vi]
客戶對于這些博客文章的反應(yīng)讓我們感到吃驚。在介紹過自己是如何把事情搞砸后,客戶對我們表示了感謝。這樣的透明度是一種好事,相比供應(yīng)商與客戶之間傳統(tǒng)的互動方式,可以塑造出更富有成效的關(guān)系。
業(yè)務(wù)與工程的融合
過去,很難將業(yè)務(wù)和工程問題放在一起考慮,因為那樣需要花很長時間才能看到相關(guān)決策所產(chǎn)生的結(jié)果。DevOps改變了這一點。我們希望能在用戶首次與我們互動時就提供出色的用戶體驗,也許用戶只是在網(wǎng)上搜索信息,或者試用產(chǎn)品。我們希望在遙測技術(shù)的幫助下,與用戶的每次接觸都能讓用戶感到滿意,我們也會盡可能與主要客戶進(jìn)行一對一互動,借此更好地了解他們的想法。
例如,我們會將每個客戶的發(fā)展歷程看作是一個漏斗,而我們會面臨很多漏斗。這個歷程可能始于某個網(wǎng)頁,通過試用,最終成功使得用戶開始在Azure、本地,或其他地方部署。如果在漏斗的任何一個環(huán)節(jié)我們對成功率不夠滿意,那么我們會針對改進(jìn)措施提出假設(shè),對相關(guān)變動進(jìn)行實驗,并度量實驗的結(jié)果。我們會將業(yè)務(wù)實驗與服務(wù)其他方面的實驗一起評估,例如活動網(wǎng)站、當(dāng)前和活躍用戶的月增速等。我們會謹(jǐn)慎地確保可以關(guān)注最可行的度量值,而非那些華而不實的度量值。
我們還發(fā)現(xiàn)最好能將度量值與定性的客戶反饋放在一起考慮。我們會通過多種方式收集反饋,其中最高級別的接觸是“頂級客戶項目”。我們會通過這些項目讓工程團(tuán)隊的成員自愿地與某個最重要的客戶建立聯(lián)系,大約每月進(jìn)行一次交流。借助這樣的機(jī)會,我們可以更清楚客戶喜歡什么,不喜歡什么,有什么愿望或困惑等,當(dāng)然具體情況是不能在這里公布的。我們還有一個主要由MVP以及親密客戶組成的內(nèi)部“圈子”,我們會大約每周一次與他們通過在線會議分享想法。他們會對假設(shè)階段的場景發(fā)表自己的看法,通常這會以故事板的形式進(jìn)行,并會在實際執(zhí)行前很久就開始對優(yōu)先處理的工作發(fā)表意見。此外我們還有uservoice.visualstudio.com?等渠道,供所有人提供建議并投票。
經(jīng)驗:卓越與否用實踐來證明
隨著接受DevOps,我們需要從七個實踐領(lǐng)域?qū)唧w的成長進(jìn)行評估,我們大家都認(rèn)為這已經(jīng)是“新時代的敏捷”。
圖17:在掌握DevOps的過程中,我們試圖通過七個實踐領(lǐng)域進(jìn)行持續(xù)的完善和改進(jìn)。
敏捷的調(diào)度和團(tuán)隊。這一點與敏捷是相同的,但更輕便。涵蓋多個領(lǐng)域的功能小組從一個通用的產(chǎn)品積壓工作列表中領(lǐng)取任務(wù),通過盡可能少的工作完成整個流程,并在每個沖刺結(jié)束后交付可供部署的成果。
技術(shù)債的管理。任何技術(shù)債都蘊含風(fēng)險,最終會導(dǎo)致各種計劃外工作,例如可能干擾計劃內(nèi)交付的線上問題。我們會慎重對待任何類型的技術(shù)債,并會通過周密的安排在它們影響到所交付的服務(wù)質(zhì)量前順利解決。(偶爾可能會判斷失誤,例如上文講的VS 2013發(fā)布之前遇到的情況,但我們會通過溝通盡可能維持透明度)。
價值流。這意味著按照對客戶的影響決定積壓工作的優(yōu)先級,專注于為客戶提供價值。原本的敏捷方法中我們經(jīng)常會談到這一點,但直到現(xiàn)在,通過DevOps遙測機(jī)制,我們才可以度量這樣做的成功與否,以及是否需要調(diào)整方向。
基于假設(shè)的積壓工作。在使用DevOps前,產(chǎn)品負(fù)責(zé)人會根據(jù)有關(guān)人員的最佳反饋“美化”積壓工作列表。但現(xiàn)在我們將積壓工作視作一種假設(shè),需要將其轉(zhuǎn)變?yōu)閷嶒?#xff0c;因此需要收集能夠支持或減少這些假設(shè)的數(shù)據(jù)。我們會根據(jù)證據(jù)來決定后續(xù)的積壓工作,以及到底是堅持進(jìn)行(更多工作)還是嘗試(其他不同的思路)。
證據(jù)和數(shù)據(jù)。我們對一切進(jìn)行了監(jiān)控和數(shù)據(jù)收集,不僅僅是為了了解運行狀況、可用性、性能,以及有關(guān)服務(wù)質(zhì)量的其他指標(biāo),這也是為了更好地理解使用情況,并收集與積壓工作的假設(shè)有關(guān)的證據(jù)。例如,我們會對有關(guān)用戶體驗的改動進(jìn)行實驗,衡量對漏斗轉(zhuǎn)化率的影響。我們會對不同用戶群的使用情況數(shù)據(jù)進(jìn)行對比,例如工作日和周末使用情況,借此假設(shè)出每種情況下可以繼續(xù)改善體驗的方法。
生產(chǎn)為先的心態(tài)。只有服務(wù)質(zhì)量始終卓越,才能得到可靠的數(shù)據(jù)。我們會不斷追蹤線上網(wǎng)站的狀態(tài),對造成各種問題的根源進(jìn)行補(bǔ)救,主動發(fā)現(xiàn)性能方面的異常,并判斷造成這種情況的原因。
為云做好準(zhǔn)備。只有對架構(gòu)進(jìn)行持續(xù)完善,重構(gòu)為更獨立、相互分離的多個服務(wù),并借助公有云靈活的基礎(chǔ)架構(gòu),才能提供24x7x365不間斷運行的服務(wù)。如果需要更多容量,可以從云(我們使用了Azure)中獲得。我們開發(fā)的每個新功能都首先以云端為主,隨后才會被納入本地運行的產(chǎn)品,僅有少數(shù)有意為之的例外情況。于此同時,我們可以確信自己的產(chǎn)品經(jīng)過了大范圍的加固,并能通過客戶的堅持使用獲得持續(xù)不斷的反饋。
參考:
1.?相關(guān)詳情回顧請參閱:http://blogs.msdn.com/b/bharry/archive/2013/11/25/a-rough-patch.aspx
2.?具體范例可參閱?Gartner ALM Magic Quadrant
3.?Ries, Eric (2011), The Lean Startup.
4.?Liker, Jeffrey (2003), The Toyota Way: 14 Management Principles from the World's Greatest Manufacturer
5.?參閱:http://aka.ms/redblueteam
6.?https://msdn.microsoft.com/en-us/library/dn589784.aspx
7.?http://techblog.netflix.com/2012/07/chaos-monkey-released-into-wild.html?以及http://blog.smarx.com/posts/wazmonkey-chaos-monkey-for-windows-azure
8.?http://en.wikipedia.org/wiki/5_Whys
9.?示例:https://social.msdn.microsoft.com/Search/en-US?query=outage&beta=0&rn=Brian+Harry%26%2339%3bs+blog&rq=site:blogs.msdn.com/b/bharry/&ac=4
原文:https://mp.weixin.qq.com/s/avcAo1XtY71H_ItJNhL6EQ
.NET社區(qū)新聞,深度好文,歡迎訪問公眾號文章匯總 http://www.csharpkit.com
總結(jié)
以上是生活随笔為你收集整理的大规模开发团队如何实现DevOps转型? 来自微软全球开发平台工程团队的实践经验的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: ABP前端使用阿里云angular2 U
- 下一篇: kubernetes实践之运行aspne