軟件開發過程當中,開發成員常常須要把本身工做集成到項目中,一般每一個成員天天至少集成一次。若是項目較小,對外部的依賴較小,那麼軟件集成可能不會是什麼問題。可是目前不少軟件項目特別是互聯網項目面臨着需求不明確,系統架構複雜,任務分配混亂等一系列問題,從而給持續集成帶來許多麻煩。也給整個項目帶來沒必要要的風險。所以一個有效的持續集成系統愈來愈重要。前端
個推平臺是一個極其複雜的分佈式系統,整個系統包含了 RPC 調用,高速緩存,集羣同步等各類複雜的場景。整個團隊只有二十來我的卻維護了近百個模塊的開發和測試工做,若是沒有一套有效的機制,很難想象如何完成這些任務。持續集成在其中扮演了很是重要的角色,藉助於 Git、Docker、Jenkins 以及 Nexus 等工具,咱們搭建了本身的持續集成環境,並一步一步的摸索出了本身的最佳實踐,這篇文章將會和你們一塊兒分享咱們是如何利用這些技術提升團隊的生產力的。git
相比於同類項目版本系統,git有一項很是顯著的優點,就是版本分支(branch)的合併(merge)十分方便。web
做爲一種新型的虛擬化方式,相對於傳統的虛擬化方式有着衆多的優點。例如,docker虛擬容器的啓動能夠在秒級實現,而且對系統資源的利用率很高。另外,docker的管理,遷移和擴展也更輕鬆有效。docker
Jenkins爲開發人員提供了很是有效的持續集管理。其強大的插件系統和明確的構建邏輯,使得構建流程的建立很是簡便。後端
測試做爲軟件項目重要的一環,通常都須要開發團隊搭建一套獨立的測試系統。但做爲持續集成的一個環節,此測試系統又異於通常的測試系統。主要緣由爲,持續集成測試系統主要用來作迴歸測試,並且須要支持快速大量的代碼升級。基於docker的特性,以及持續集成的需求,個推採用docker爲持續集成搭建了一整套測試系統。緩存
鏡像準備:docker 的運行基於鏡像文件,而每一個項目所需的鏡像文件又不一樣。所以須要獨立分析每一個項目的需求以及將來擴展須要,建立出不一樣版本的鏡像文件。目前,個推主要有4大類鏡像,分別支持前端,後端,工具類,以及其餘項目。之前端爲例,個推採用了先後端分離的開發模式,所以此鏡像主要用來支持web 前端的服務運行。服務器
素材準備:爲了能在docker裏運行所須要的服務,須要docker實例中安裝相應的包。 通常有兩種方法,一種爲將相應的素材與鏡像文件相綁定,另外一種以docker 卷的形式動態映射到docker實例。 兩種方式有其優劣,第一種方式使得每次docker 容器的啓動很是迅捷,而第二種方式則更爲靈活。這個須要根據不一樣的需求選擇合適的方式。架構
下圖爲docker 在整個持續集成系統中的做用。Jenkins 做爲主服務器將代碼和docker 統一的管理起來。
前後端分離
以一個假設名爲user模塊爲例,以開發人員的視角闡述了持續集成的邏輯。從下圖中能夠看出,咱們系統的git分支包括dev,master兩個分支:分佈式
dev:開發分支,開發人員維護,開發人員將最新代碼提交到這個分支,Jekins監視這個分支,任何代碼改變都會觸發自動化測試
master:發佈分支,這個分支上的版本是自動化測試經過後的版本,且自動化打包監控這個分支
圖中的每一個長方形表明一個Jenkins Job。下面將對每一個Job進行說明:
user: 監控user代碼庫的dev分支,當每次有新的代碼提交時,就會自動觸發構建任務。編譯代碼,同時生成code style,測試覆蓋率等關於代碼質量的報表。成功後將觸發user-docker任務。
user-docker: 打包user工程,重啓user的docker實例以便於使用全新的user包。成功後將觸發testcase任務
testcase: 驗收測試,檢測改變是否知足業務需求所定義的驗收條件。成功後將觸發marge任務
merge:將user的dev分支merge到master分支
user-pkg: 監控user代碼庫的master分支,當有代碼改變時,執行mvn package
打包操做
通過上面的幾個步驟,從代碼提交到打包的整個過程就自動化起來了。
目前愈來愈多的公司開始重視持續集成系統,可是缺少定製化的系統真的能知足複雜的需求嗎?當模塊之間的聯繫愈來愈複雜,集成的頻率愈來愈大,運行環境的不斷升級 等等,缺少定製的持續集成系統是否能達到預期,個推在docker 上找到了問題的答案。 雖然仍然有許多挑戰,但隨着技術的升級和完善,咱們終會越作越好。