閱讀851 返回首頁    go 阿裏雲 go 技術社區[雲棲]


大規模代碼構建技術實踐

在雲效持續集成持續交付專場直播中,阿裏技術專家何衛龍為大家帶來了《大規模代碼構建技術實踐》的分享。本次分享主要從持續集成的背景,持續集成平台的演進過程,以及如何進行大規模持續集成構建三部分展開,內容精彩,不容錯過。


以下內容根據講師PPT和視頻整理而成。




大師Martin Fowler認為持續集成是一種軟件開發實踐,在實踐中團隊開發成員會頻繁的進行任務的集成,通常每個成員每天都會集成一次,也就意味著每天可能會發生多次集成。每次集成都通過自動化的構建來驗證,從而盡快地發現集成錯誤快速進行修複。


e413bc5d64c628b2191ad4070f38bdf2578f0b02 


如上圖所示,一個完整的持續集成環節包括:首先項目經理創建一個項目,將項目成員添加到項目中;開發人員在項目中拉取開發分支進行代碼開發,在開發過程中,開發人員將代碼提交到代碼倉庫(如SN、GIT);後端的持續集成任務會定時掃描代碼倉庫,如果發現代碼有變更,馬上觸發一次CI構建,一次CI包括源碼下載、代碼編譯、靜態掃描、單元測試、覆蓋率分析、sona檢查、環境打包部署、自動化用例執行等;再以消息的形式反饋結果給代碼提交人或者項目關注人。消息的形式有兩種,一種是即時消息,如阿裏內部的旺旺、釘釘,讓開發人員第一時間收到CI結果概況,如有問題,可以進行快速修複;另一種是郵件通知,可以看到CI結果詳情,幫助問題的定位和跟蹤,有益於驅動大家修複問題。


持續集成的優勢


持續集成有哪些好處呢?


 

087cbfb94d80aaffaa10f8888c2e3303acf106ae 


首先來看一幅圖,大家應該都比較熟悉,冰山一角,如果把它移植到研發測試流程上麵來講,我們看的到的冰山,就好比開發階段發現的Bug,比起海麵以下的冰山,簡直就是小巫見大巫。因此,持續集成給我們帶來的直接好處,就是不斷的發現海麵以下的Bug,讓我們能在開發階段盡可能多的解決問題;其次,Bug越往後麵發現,處理它的成本會越高,付出的代價也越大,因此,持續集成能幫助到我們降低項目研發成本;最後,如右側圖片所示,當持續集成不斷的完善項目時,會潛移默化的推動著我們測試前移的動作,從沒有集成的1,到集成初期的2,最終不斷完善的集成3,成本越來越低、代碼質量越來越高、發布時間越來越短 、從而使產品的品質越來越好。


持續集成涉及整個項目生命周期的人員,包括需求方、開發、測試、產品經理等。對於開發人員,他們希望能有單測、覆蓋率、findbugs、sonar等自動化集成工具,盡早發現缺陷,這樣流入測試環節的問題就會變少,從而保證代碼質量;對於測試人員,他們希望盡早集成發現缺陷,提高待測質量,降低項目風險;產品經理則希望項目能按期、保質保量的安全上線。因此我們需要一個持續集成平台來保障上述利益。

 


下麵來介紹一下平台演進的過程。


c2c18d9883c0877daa7a4921d2b19ed238d206aa 


主流的持續集成工具主要有:


  • Jenkins,它的前身是Hudson ,是一個可擴展的持續集成引擎。它的功能比較強大,支持分布式任務構建。
  • GoCD,一款先進的持續集成和發布管理係統,由ThoughtWorks開發,其前身為CruiseControl,是ThoughtWorks在做谘詢和交付交付項目時自己開發的一款開源的持續集成工具,ThoughtWorks專門成立了一個項目組,基於Cruise開發出了GoCD這款工具。使用GoCD來建立起一個項目的持續部署pipeline是非常快的,非常方便,它的不足點是插件較少、開源時間短、用戶群體較小;
  • Apache continuum,其安裝和配置都較為方便;
  • Strider 是一個開源的持續集成和發布服務器,使用 Node.js 開發;
  • TeamCity是一款功能強大的持續集成(Continue Integration)工具,包括服務器端和客戶端,目前支持Java、.Net項目開發,是一款商業軟件;
  • Atlassian Bamboo 是一款持續集成構建服務器軟件(Build Server)商業軟件;
  • Travis CI是一個基於雲的持續集成項目,目前已經支持大部分主流語言了,比如C、PHP、Ruby、Python、Nodejs等。和Jenkins類似,Travis CI也是開源的,不過Travis和Github集成非常緊密,官方的集成測試托管隻支持Github項目, 不過用戶也可以搭建一套自己的方案。 


通過對上述持續集成工具的比較,阿裏最終選擇了Jenkins這一工具,Jenkins作為一款開源軟件,有著豐富的插件(目前已達幾百個),還可以自定義插件以及修改或增加Jenkins擴展點,來進行Jenkins功能擴展。


f65c5327b6035a2831191fedd1d52fe0575e6e95 


對於小團隊而言,Jenkins完全可以滿足需求了,但是對於一個成百上千,甚至更多人的團隊來講,就顯得有點弱了。第一,Jenkins不能自動創建Jenkins任務,必須在Jenkins平台上手工創建,大大降低了集成效率,而且需要大家都掌握創建Job的方法以及Job上的配置,不利於工具推廣;第二,其數據顯示不能定製化,如果想要集成數據在一個頁麵上顯示,那麼Jenkins是無法滿足這個要求的;第三,數據不能持久化,目前Jenkins的數據是通過文本的方式保存的,而且量很大,不利於數據維護和後續的數據分析;第四,執行機掉線沒有報警功能,不會及時通知管理員及時處理;第五,數據反饋機製比較單一,Jenkins僅支持郵件的方式進行發送通知;第六,通過項目信息查詢任務困難,Jenkins沒有項目的維度,隻有Job的維度,不方便查找。


cdb350934f82268d16a2618d9ce21dc667f8a270


 

因此,單測集成平台Amon應運而生,它始於2012年,目前已有10多家公司,正在使用這一產品。Amon的優勢在於其任務全自動構建,並支持大規模集成、數據持久化,具有豐富的報表和多維度的數據分析,Amon和Jenkins詳細功能對比如上圖所示,這裏不再一一敘述。


dac0b8468c443e29b4e8f19dd155f0f2070a2969


我們針對Jenkins插件進行了新增和修改,以便它們適應於Amon,主要包括:


  • Maven pom內容修改插件,它能滿足一些特定功能;
  • Maven多模塊構建插件,支持多路徑發現pom文件;
  • MQ構建結果通知插件,它能夠通過消息的形式發送到平台;
  • Hosts修改插件,以此支持特定服務的測試;
  • Cppcheck編譯掃描結果插件;
  • Antx文件自動生成插件;
  • 支持cobertura結果合並插件;
  • 支持cobertura增量覆蓋率插件;
  • 支持jshint掃描插件
  • 支持多執行機空間清理插件
  • Sonar-runner自動找java路徑

 


目前,阿裏內部集成狀況是支持10w+的日均構建數,平均每秒發生四次構建,這是一個非常龐大的量。我們的平台是如何來做支撐的呢?


cb26a9ef8f3d1cb1d5db2ae6a3e274d3a50b3a53 


首先,係統通過負載均衡模塊將集成任務分配至各集群中;在每個集群中都有大量Jenkins機器來做持續集成構建,它是可以進行橫向擴展的,因此我們就能很好地進行大規模的構建。在構建過程中,難免會有一些任務排隊等待,這樣會導致一些用戶等待時間較久。


我們針對這一情況進行了優化:相同集群的Slave可以靈活、自由調度,如果某台Jenkins任務比較吃緊,它就會從最空閑的Jenkins上調度一台Slave過來支持當前的任務構建,以解決任務排隊嚴重的問題。但是,過於頻繁的Slave調度勢必會影響到係統處理時間和性能。因此,接下來將詳細講解負載均衡做到最優任務分配的原理。


 efd0c600e8f965d70637bc81e7c15b94e48a0516


這裏提到的負載均衡和常見的負載均衡還是存在差異的。這裏提到的負載均衡任務集成自驅的,也就是其可以定時自動構建,因此,你不太清楚一個任務一天回構建多少次,也不清楚一次構建的時長是多少。在分配任務的時候,可能比較難以選擇,如果仍然按照平均分配的方式,勢必會形成每個Jenkins上任務個數相同,但是基於每個任務的構建時長和頻率都存在差異,這樣又會導致一些Jenkins排隊非常嚴重,那麼如何解決這個問題呢?


首先需要了解一下Jenkins中的參數:其中n表示任務數、m表示執行機數、T表示最大構建負載(T=m*8*60),如超過最大負載值,任務排隊現象會加重;Jenkins第k個任務構建總耗時用tk(tk=任務最近一次構建耗時(分鍾)*該任務曆史日均構建次數)表示。根據上述參數,可以計算出Jenkins當前的負載值H,公式為:


b2385d1b91df2f0acd1fe46438d4568e54b63afb


利用當前的負載值,進行任務分配,做到最優化:當任務分配到Jenkins時,同時需要增加Jenkins的負載值以及修改該任務的平均耗時和平均構建頻率,不斷地調整,以便於趨於穩定;當任務關閉時,需要減去相應的時間來調整負載值。該算法的思路較為簡單,但實現時比較困難,主要是由於任務的耗時和頻率會發生變化,需要實時調整以改變負載值,讓集成任務分配到最合適的Jenkins上去。




e38faead9daee6c9183b55daba6b9d153e5b01cd


詳情點擊>>











最後更新:2017-07-24 21:33:04

  上一篇:go  用“Keras”11行代碼構建CNN
  下一篇:go  CentOS6 安裝並破解Jira 7