本文整理自國內首屆 Jenkins 用戶大會演講《讓大象跳舞,手Q研發體系與工具實踐》web
講師 | 潘金赤
編輯 | 白凡docker講師簡介
潘金赤騰訊高級工程師,畢業於華中科技大學,碩士學歷。至今已在騰訊工做6年,任研發平臺工具負責人。安全
騰訊內部你們更傾向於根據本身的業務特點作平臺的封裝,我想以「手Q」爲案例看看騰訊內部是如何完成持續交付的。框架
今天的交流主要分爲三大話題:運維
一、介紹手Q現狀,以及存在着怎樣的問題和壓力分佈式
二、介紹內部各研發階段的平臺工具支撐體系ide
三、介紹手Q項目是如何將平臺工具進行串聯,達到怎樣的持續交付效果函數
根據騰訊公司Q3剛剛發佈的財報數據,「手Q」月活已經達到了6.5億,同時在線達到了2.7億,這裏的同時在線包含PC和「手Q」,「手Q」已經佔了很是大的比重,超過50%。工具
騰訊剛公佈的Q3財報來看,手Q的月活達到了6.62億,PC端手Q端同時在線超過2.68億,在國內外的即時通信領域,都是極有份量的一款產品。而在即時通信之外,他還承載了很是多的社交及娛樂場景,公司內的各項產品也經過手Q平臺提供功能和服務,從更便捷的觸達到用戶。性能
那究竟是怎樣的一個團隊,打造出手Q這樣子的服務億萬用戶的產品呢?咱們來看一張手Q項目團隊的照片。實際上是給你們開個玩笑,不過這張照片也確確實實反映出手Q團隊的特色,一個是人多,而手Q的每個版本就像一輛車,這麼多人都在努力遇上這趟車。
「手Q」在版本發佈上,面臨這些挑戰:
橫跨公司7大事業羣,20多個部門,研發測試超3000人
每一個版本300+需求,10萬+行代碼,5000+測試用例
每一個版本新建分支上百條
這裏要介紹一下手Q的多版本並行模式,一般同一時間點會有3個版本會在進行中,每一個版本交錯疊加,一個版本的完整週期雖然須要3到4個月,可是相鄰兩個版本的發佈間隔只有1到1.5個月,這樣不只能夠持續刺激手Q年輕用戶的新鮮感,也保證團隊內各個角色成員在任何階段也都能高效滾動起來。
剛纔提到了拉分支,手Q的絕大部分需求都是在分支上開發完成的,每當一個新特性要啓動,都會從主幹上新拉出一條分支,在這個分支上進行需求開發。期間還需按期同步主幹上的變更,而當功能開發完成後就會合回主幹,而且將此分支凍結再也不繼續作其餘功能開發。
系統測試經過後,版本準備發佈時,會再拉一條發佈分支出來,在發佈分支上作最後發佈前的確認。固然,若是此時若是還有bugfix一樣也須要合併到發佈分支去,直到最終發佈結束。發佈完成後發佈分支也將凍結再也不復用。這個就是手Q一向的研發模式。
在分支開發的過程當中,「手Q」這麼大的規模,這麼大的團隊,遇到哪些問題呢?這個問題可能不只僅是「手Q」團隊會這樣,我相信在公司或者項目的規模達到必定的層級以後,均可能遇到這樣的問題。體如今研發階段主要有這四類。
一、主幹上面變更太大,幾千人都在開發,提交時容易漏合、錯合或者把別人的代碼覆蓋
二、測試的時候須要頻繁的換包,常常測到一半,發現包更新了,須要從新換包來測
三、主幹不穩定會致使主幹編譯失敗,過多提交致使定位致使失敗的提交記錄困難
四、部署的階段,涉及20多個部門,常常須要所有確認後才能部署,致使部署推動很是困難低效
爲了優化上述問題,咱們經過平臺工具以及適度的流程創建,來將團隊的研發效率提高起來。而在手Q團隊內部,有着很是多的優秀平臺和工具,來幫咱們節省開發測試成本,並在一系列完善的流程指導下,規範並有序研發過程。下面咱們將以研發階段爲劃分,圍繞幾個有表明性的平臺工具作一些詳細介紹。
這個系統是手Q項目一切自動化管理的源頭,他記錄了手Q的各個版本及分支信息,他主要包含如下三部分功能。
第一,分支管理,全部版本和分支不容許手動建立,而是來平臺申請後自動建立,分支申請時關聯好需求、敏感文件等信息,分支建立成功後不只僅會自動建立好持續集成構建任務,同時也會持續監控分支需求狀態,同步分支開發進度。
第二,代碼管理,建立分支後,自動會自動每日定製幫開發完成主幹最新版本的同步,分支負責人可自定義同步策略,代碼出現衝突時也能預警並自動處理,同時系統會對分支定義的敏感文件進行保護,一旦敏感文件發生變更也會觸發預警或拒絕提交。
第三,權限管理,開發必須經過配置管理系統來完成權限的申請,保證每次權限操做有據可查,這樣能夠很好的作到權限的隔離,保證權限最小化,並且一旦有團隊人員發生變更,系統會自動完成權限清理,防止信息泄漏。
合流的意思是把代碼從分支上合到主幹上,雖說是很是簡單的動做,但其實在實際的項目當中,會遇到很是多的問題。尤爲是那麼多人,你們都想在同一個時間點完成代碼的提交,常常須要排隊甚至睡在公司等待版本合流。針對這些亂象,咱們搭建這套合流系統來解決出現的問題。
咱們從這五個方面去完成合流的效率提高:
代碼掃描有很是多優秀的工具,包括PMD。咱們內部的代碼掃描工具將業界的優秀工具實踐以及咱們內部自研的工具進行結合,針對內部業務的特性作了適配和改造,在工具的基礎上封裝了兩千多個規則級,這個規則級能夠給各個業務不一樣場景作支撐的,各個業務也能單獨定製本身所關注的規則集。
基於那麼多工具、規則級的封裝,咱們能提供跨語言、跨平臺的代碼掃描或者代碼靜態檢查的完整解決方案,並基於這些工具,支持到公司內部全部的平臺、語言及業務。
主要功能包括:
代碼靜態掃描
代碼分析、代碼複雜度、邏輯複雜度的統計
目前這個工具內部接入業務有60+,每月平均發現了接近3萬個問題,這個問題咱們內部統計了一下,包括代碼規範,包括空指針包括內存泄漏,這些問題團隊內部是最多的,也是須要團隊共同解決優化的。
業界有許多自動化測試的工具,例如robot,QTP等,可是在實際使用中都常常會面臨一些問題,針對手Q業務而言更加嚴重:
內部業務的改動多,尤爲是界面交互的改動是很是頻繁的
穩定性很是低,只要有任何一點界面改動以後,這些自動化用例都須要從新作調整。
咱們內部研發了這套自動化測試框架QTA,實際上是整套完整的UI自動化的解決方案,涵蓋了PC端、web端、安卓、IOS,也包括協議自動化,這個框架裏面所有整合了。
完成了對各個端底層控件的識別和操做,這套框架也把這些控件封裝成了對於內部業務來講比較好理解,也比較好作封裝的對象。
測試基於這六項寫自動化測試的用例,能夠操做這些用例。
編寫完用例以後,能夠經過咱們分佈式測試的執行引擎。
這裏有一份統計數據,QTA目前全部的用例有20000+,測試計劃2000多個,每月執行測試任務7萬屢次。每月跑的測試用例總數200多萬份,這個量也是挺大的。
自動化測試必需要有設備,針對「手Q」,例如說「手Q」安卓來講,必需要有安卓的測試機。這麼大的自動化測試量,咱們測試機怎麼辦?
搭建一個機房,故障時跑到機房去查,形象難看
基於這個背景咱們作了一個方案,就是安卓虛擬化,生產安卓虛擬機,全部測試在虛擬機上面完成,這樣在測試開始的時候,咱們能夠根據測試的須要去虛擬化對應的操做系統、CPU和內存的需求。
在測試完成以後自動收回,這個跟早上說的構建跟docker的方案有點相似的,這個是針對終端的虛擬化。
這樣的虛擬化以後咱們還可以經過web方式,指定某檯安卓虛擬機完成UI操做或者是命令行操做,或者是文件上傳下載,咱們能夠直接經過本地,坐在電腦前,經過一個網頁就能夠看到某一臺機器測試狀況是什麼樣的。
與實體機相比,虛擬機有明顯好處:
節省了設備採購和維護成本
如今咱們在「手Q」項目內部的,以及SNG內部多數的自動化測試都是經過虛擬機完成的
專項測試,我認爲這是「手Q」團隊作的很是深刻的一個領域了。專項測試涵蓋資源類性能,交互類性能、穩定性、兼容性、安全方面的測試。
咱們團隊針對這裏的每一塊領域,都有一整套比較完整的解決方案,在版本上線前,甚至版本發佈後都可以幫助業務團隊定位以及分析各個環節當中出現的性能問題。這裏也介紹團隊中比較有表明性的兩個工具。
一、New Monkey,這個是在Monkey工具的基礎上研發,有更多符合咱們的優點:
經過對控件賦權,保證各個UI控件都有同等機率被測試。
經過觸發式自定義腳本,幫助進入複雜路徑,保證更深層次的控件也可以操做到
他在記錄crash堆棧的同時,能將crash問題聚類,避免同類問題反覆告警;此外它還能夠和其餘專項工具結合,在穩定性測試的同時就能夠採集上報其餘性能指標
二、APM是屬於一個資源類性能、交互類性能數據採集和分析的SDK。
各個業務接入這個SDK之後,能夠很方便的完成好比說我在某個頁面或者說某一個控件操做時的時延,或者說用戶在使用某個功能的流暢度,以及丟幀的統計上報。
關於專項測試其實還有很是點能夠深挖,這裏介紹的幾乎每個專項範疇,咱們的專項測試團隊都有在外面的各個大會上作過度享,包括剛纔我看到高效運維社區的視頻廣告,我就看到了一位來自咱們團隊的同窗,常常在外面分享性能測試及優化之道。所以這裏我就不深刻介紹了。
爲了表示對專項團隊的敬佩和歉意,我幫他們打個廣告,這本書是團項測試團隊的嘔心瀝血之做,將他們在專項測試多年的經驗及經典案例聚集的一本乾貨全集,是Android APP性能和開發工程師的必備案頭手冊。
衆測實際上是一款基於衆包概念的平臺,內部業務經過衆測這個平臺投放測試任務,外部用戶經過衆測的網站或者APP上領取並執行指定任務,提交任務反饋。
咱們會對用戶執行任務的狀況以及反饋問題的有效性進行校驗,並將真實問題轉化爲產品的需求或bug進行進一步優化, 並對用戶進行獎勵。
經過這個衆測能夠達到幾個目的。
第一,兼容性測試,由於咱們內部作測試,包括以前也聊了一些測試團隊,他們機型再怎麼豐富,畢竟考慮到成本問題,好比說像咱們以前用到大連兼容預測團隊,機型就是200多,但外面用戶機型是千差萬別,經過衆測的模式能夠很好的實現兼容性的問題。
第二,功能用例覆蓋,每一個用例手工執行是很是耗時的,是否能夠把沒有發生太大改變的用例,或者基礎的功能用例丟給外部跑,讓他們幫咱們保證這個功能沒有問題,咱們內部就能夠根據其餘的策略,好比說精準測試,或者freetest,來發現更多複雜交互問題。
第三,這裏單獨列一點,就是IOS灰度困難的問題,之前IOS要灰度就只能經過一個渠道,就是越獄用戶,如今IOS用戶越獄人數都愈來愈低,IOS用戶都不肯意越獄,這樣咱們內部產品灰度的難度就愈來愈大。衆測完成了跟蘋果的對接,非越獄用戶能直接完成體驗版本的下載,保證咱們IOS的灰度還可以按照複合蘋果規定的方式進行,同時還能保證必定的用戶量。
以上是咱們衆測平臺以及APP的介紹。衆測作了差很少接近兩年的時間,目前幫咱們內部投放了兩千屢次任務,平均每月都有三十多個任務投放,已經累積幫咱們發現了至少2000多個BUG。採集標註的素材也達到上萬份。
來JUC不介紹持續集成好像不行,其實我以爲咱們內部的持續集成作的挺通常的,由於得益於有了KK以及他的團隊在Jenkins這塊不懈的努力,我以爲任何團隊均可以在Jenkins的基礎上快速的搭建起一套本身的集成系統。我認爲一套合格的持續集成系統,須要知足如下5點要求
咱們但願每次構建就可以當即觸發編譯,當即觸發自動化測試,但在「手Q」內部這樣作不到:
一方面是由於代碼確實代大了,編譯慢,測試花的時間有點長
爲此咱們只有適當拉長檢查的間隔,只對對dailybuild進行檢查,咱們內部叫作晨報監控。晨報監控任務在剛拉分支時就能夠默認建立好,同時能夠靈活選擇須要執行哪些工具測試,天天早上都會自動的拉取最新版本完成build和測試,測試經過後生成每日基線,編譯或測試不經過時就須要相關負責人儘快解決問題。
此外每日監控的測試結果數據也能夠複用於後續的其餘測試場景,好比同個基線的安裝包若是要發起合流,可直接拉取晨報監控時的測試結果,無需重複再執行測試。
以上介紹了咱們內部用到的比較有特點的研發平臺和工具,其實基本上咱們內部用到的比較有特點的研發平臺都已經作完介紹了,這裏也想和咱們DevOps裏面有一點想作匹配,咱們怎麼樣可以保證整個研發環節出現的瓶頸可以給到內部很好的正向反饋,可以持續的讓內部項目持續優化,或者說把一些問題轉化成新的需求,這些信息如何能有效的量化並很好的呈現出來呢?
過程度量和預警,就是將各個階段、來自各個平臺和工具的數據予以彙總,給到團隊一個全景視圖,例如從需求狀態數據,我能夠知道當前版本需求開發進度如何了。
從開發階段,我能評估出當前代碼變化趨勢及提交頻度。以及某些文件是否屬於頻繁操做文件,這個文件是否是該去解耦了。
測試階段咱們看到隨着測試進行,咱們BUG有沒有收斂,這個版本有沒有質量風險;編譯階段根據構建的時長的分佈,咱們要不要作構建編譯的優化,或者說增長構建的集羣。
發佈階段我能知道如今處於什麼進度了;而版本發出去後,我能夠很清晰的看到當前版本的crash數據是怎樣。
除了單項數據的查看,各個業務還能夠針對各個指標來配置閾值,當指標超過閾值後,說明項目存在風險,項目團隊須要採起措施儘快規避風險。過程度量和預警這套服務監控着整個環節是否正常並實時反饋當前數據,一旦有特殊情況立刻告警出來。
在研發環境當中那麼多流程,那麼多平臺,其實他們就有點像是一個流式的,在各個環節和下一個環節都是經過數據或者說一些過程階段性的輸出來保證咱們各個環節的信息都是串聯的。
在需求評審經過後,直接與開發的代碼及測試的用例進行關聯。而開發的代碼必須由配置管理系統完成權限的控制,當開發完成分支上的開發,由合流系統來輔助完成代碼的合併。合流及測試過程當中都會須要調度各種自動化測試工具。
開發拉完分支,持續集成系統就會按照策略開始自動溝通,同時也會由晨報監控來把控構建產出的穩定性。團隊成員能夠很方便的獲取到最新的安裝包進行功能體驗,當測試和體驗徹底經過後,通過發佈管理的流程審覈及操做,最終發佈至外網。
此時外網啓動相關監控,監控及用戶反饋又將轉化爲新的需求,進入到下一輪版本迭代中。而在整個流程中都有數據度量及預警的監控和督促,讓整個流程能夠跑的更快一點。
這一整套平臺工具爲手Q項目帶來了很是大的收益。
在開發階段,由於不須要人工操做建立分支及權限開通授予,大大的下降了配置管理員的人工成本;由於分支和主幹每日進行自動同步,保證主幹和分支的差別最大不超過一天,分支主幹差別變少了合入的衝突也會減小;
而在分支作代碼合入時權限是獨享時,能防止我剛同步完提交時又提示要更新,在開發階段作的這麼多工做,都是爲了把質量風險前移,越早暴露問題,對項目的總體影響就越小;
而在測試階段,咱們經過各個工具明確了功能准入標準,固然自動化達標率也是標準之一,另外由於這些平臺工具的支持,讓測試效果和效率都能獲得提高。
對於構建階段最大的提高,不只僅是在於成功率的提高,更可能是在於明確主幹問題的責任人,出問題了就能快速解決。而在發佈階段,保證整個發佈環節嚴謹不出錯漏,同時又能減小單點依賴提高效率。這一系列的改造優化,都不斷的手Q的研發及持續交付流程越跑越快。
這裏還想額外講一下,由於以前咱們提到,咱們在作優化的時候,必定是平臺加工具、加流程,剛纔介紹的是平臺和工具,咱們是怎麼在流程上完成優化的呢?這裏我拿「手Q」合流這一點作一個流程介紹上面的分享。
剛纔看到有合流系統,有自動化測試、代碼掃描工具爲這個合流過程作的加速。但在流程上,其實在合流這裏體現的很是明顯,剛纔說合流分三個階段,第一個階段要完成這麼多檢查,但這個檢查當中其實除了需求狀態檢查、分支同步檢查、工具的檢查之外,這些是必需要作的,就是全部在合流以前所有要作的。
但還有不少是流程上作考慮,好比說代碼何如資格檢查,什麼是何如資格檢查?每一個新同窗進入「手Q」項目,在容許參與「手Q」開發過程以前,他必需要通過培訓、考試,並且考試必須達到一百分。
你必須得知道合代碼怎麼操做,遇到代碼衝突怎麼解,這些點必須考試經過才能夠操做,不然可能會影響整個項目。
第二個是權限,此前說了權限徹底由系統完成權限的和收回,並且必需要把整個項目的主幹權限收回來。不少項目剛開始的時候就被這點難倒了,若是沒有主幹權限萬一之後有什麼緊急狀況怎麼辦?最終流程帶來的效果,讓他們意識到這樣作是有好處的。
第三點,合入後檢查和權限釋放更加是一個流程不斷優化很是明顯的體現。之前咱們是必須合完代碼,進行功能測試,測試經過後才能釋放權限。後面咱們作到由工具自動測試完成之後就能夠釋放權限。
再到後面咱們能夠確保自動化測試穩定性,確保代碼開發合入過程當中有必定的標準、規範的,所以如今是隻要把代碼合進去,包可以編出來就可以釋放權限。這樣流程不斷的演變和優化從而達到最終效果。
這裏也能夠看一下這樣規則帶來效率的提高。咱們如今「手Q」那麼多的分支,平均合流的時間,這個是指從提交合流申請開始直到最終合流所有結束測試經過,最快一個半小時,最慢18個小時。
可能你們以爲這個數據不夠直觀化,咱們拿一個對比數據。合流系統上線以前平均一個流合完要須要115個小時。系統上線初期,這個時間縮短到22個小時。
如今穩定了,你們比較認同,熟悉度比較高了,如今6個多小時完成合流了。並且這裏強調一下,這個6個多小時並不表明整個過程都須要阻塞式的,真正須要排隊的只有提交代碼的那段時間,而這段時間咱們也限定了不能超過1個小時。
咱們也會對沒有在1小時內完成代碼提交的分支作一些分析和進一步優化,來繼續縮短這個流程。因此從這裏其實咱們能夠看到,雖然咱們有着這麼複雜的流程和規則,可是咱們的效率仍是挺高的。這裏得益於以前平臺和工具及規則的指定,關鍵點都在於提高自動化程度。
咱們最後看一下「手Q」這套研發體系的效果,1.5小時能完成合入,3天內所有完成,80%以上的分支合入是準時的。版本發佈的時候95%以上的Bug都可以解決,1月到1.5月發佈一個版本,這樣咱們跑了34個版本了。
最後嘗試作一下總結,我認爲「手Q」在持續集成和持續交付這塊,體現的幾點特質,正好也是跟所謂敏捷開發及DevOps的基本理念,或者說幾個比較重要的基本元素是符合的。
也就是流程、技術跟組織。制定明確清晰的準測,確保流程執行有效,最重要是確保的能到團隊成員的認同和準時;在流程基礎上,經過高度自動化來提高流程效率,並將流程串聯起來保持數據通暢,下降人工值守場景避免出現單點。
而組織不只僅在於人,更重要是在永遠不知足現狀的團隊,咱們經過過程分析瞭解當前項目進程,提早周知項目風險,而且無論反思研發環節中的問題,反推流程和工具的做出不斷的改進。經過這三者的結合,讓項目越轉越快越轉越順暢。