基于Jenkins的持续交付全流程设计与实践
1 從理論開始
什么是DevOps?
近年來,隨著DevOps理念的逐漸深入人心,企業(yè)逐漸意識到從看似重復(fù)的手工勞動中實現(xiàn)自動化流程處理,對于提高企業(yè)勞動生產(chǎn)力已經(jīng)非常重要,尤其是面向互聯(lián)網(wǎng)的開發(fā)者,往往每次上線時,最大的挑戰(zhàn)并非需求的走查或測試和改bug,而是由于發(fā)布的流程不夠規(guī)范,將成果發(fā)布到目標(biāo)環(huán)境后可能造成的配置錯誤或引發(fā)其他已知未知問題所造成的額外工作量,使得生產(chǎn)環(huán)境的發(fā)布流程總會存在不順利。
而DevOps則致力于統(tǒng)一整合軟件開發(fā)和軟件運維,其特點是強烈倡導(dǎo)對構(gòu)建軟件的所有環(huán)節(jié)(從集成、測試、發(fā)布到部署和基礎(chǔ)架構(gòu)管理)進行全面的自動化監(jiān)控。目標(biāo)是縮短軟件開發(fā)周期,提高部署頻率和更可靠的發(fā)布,與業(yè)務(wù)目標(biāo)保持一致。
在實際操作過程中,對于許多公司而言,開發(fā)者和運維者并沒有明確的界限,而且即便將運維與開發(fā)的崗位職責(zé)分開了,也并非意味著雙方的職業(yè)發(fā)展方向?qū)⒋蟛幌嗤嶋H上在實際操作過程中,開發(fā)人員和運維人員依然會使用相同的工具、統(tǒng)一的流程、一致的管理思想,并通過一系列管理手段和工具實現(xiàn)流程的優(yōu)化。
什么是持續(xù)集成和持續(xù)交付?
持續(xù)集成(Continuous Integration)與持續(xù)交付(Continuous Delivery)也正是DevOps中最為基礎(chǔ)的兩種企業(yè)級研發(fā)和交付活動。
持續(xù)集成來源于敏捷項目管理思想,其核心是團隊成員應(yīng)該經(jīng)常集成他們的工作,通常每天要求集成一次,當(dāng)然也可以要求團隊成員每天集成多次。每次集成之后,會通過持續(xù)集成工具自動運行自動化的構(gòu)建手段(例如編譯、單元測試、集成測試、系統(tǒng)測試),并對集成后的成果進行驗證,從而實現(xiàn)了企業(yè)管理流程中盡早的發(fā)現(xiàn)未知問題的目標(biāo)。而在傳統(tǒng)的軟件交付中,可能會將所有問題積壓到系統(tǒng)整體測試或甚至UAT(用戶驗收測試)環(huán)節(jié),使得軟件的測試時間被拉長,甚至使得軟件的問題流入到客戶現(xiàn)場,讓客戶成為小白鼠的情況時有發(fā)生。
實際上而言,看似簡單的集成,卻并非簡單,他應(yīng)該是企業(yè)管理過程中的一項鐵律,只有嚴(yán)格執(zhí)行,才能確保軟件時刻處于可用狀態(tài);否則就意味著所謂交付過程中完成進度的百分之多少,只不過是一個虛無縹緲的空口白話。
持續(xù)集成往往離不開持續(xù)交付,在喬梁老師翻譯的《持續(xù)交付》一書中,作者Jez Humber說:持續(xù)交付是一種能力,也就是說,能夠以可持續(xù)的方式,安全快速的把代碼變更(包括特性、配置、缺陷和試驗)部署到生產(chǎn)環(huán)境中,讓用戶使用。這本書的作者也在書的最后一章中指出:它(持續(xù)交付)不僅僅是一種新的軟件交付方法論,而且對依賴軟件的業(yè)務(wù)來說,也是一種全新的范式。
持續(xù)交付與持續(xù)部署看似類似,其實有所區(qū)別,前者往往是指將環(huán)境推送到用戶面前,使用戶能夠觸及和使用它們;而部署則僅僅只是把軟件包安裝到目標(biāo)計算機上,用戶可能還無法直接使用。
對于面向互聯(lián)網(wǎng)的軟件企業(yè)來說,往往都已經(jīng)在過去若干年間已經(jīng)建立了一套完整的持續(xù)集成/持續(xù)交付流程,但對于某些處于飛速發(fā)展期的企業(yè)來說,依然相對而言后知后覺,主要是由于企業(yè)過去飛速發(fā)展的背后所依托的人力物力資源,能夠足以保證企業(yè)的產(chǎn)出能夠適應(yīng)企業(yè)發(fā)展的需要,然而隨著團隊規(guī)模的發(fā)展趕不上企業(yè)業(yè)務(wù)發(fā)展的需要時,重復(fù)勞動和看似毫無價值的等待期、后期積壓的測試任務(wù)、無法有效度量的軟件功能實現(xiàn),實質(zhì)上也會造成企業(yè)的管理成本進一步提高。
從哪里可以獲得系統(tǒng)的方法論?
對于需要搭建一套完整環(huán)境的開發(fā)者來說,網(wǎng)上資料很齊全,本文也試圖盡可能的對各方面的內(nèi)容進行綜述,努力為開發(fā)者提供一個開箱即用的操作流程,但是對于那些想系統(tǒng)的學(xué)習(xí)持續(xù)交付或DevOps領(lǐng)域的知識的開發(fā)者來說,你其實不僅僅滿足于把環(huán)境搭起來,那么你應(yīng)該看看書。
在持續(xù)集成和持續(xù)交付領(lǐng)域有大量優(yōu)秀的作品,而我覺得來自喬梁老師的作品《持續(xù)交付2.0》堪稱精品,喬梁老師是一位經(jīng)驗豐富的行業(yè)專家,在他的職業(yè)生涯中積累了與該領(lǐng)域相關(guān)非常豐富的產(chǎn)品研發(fā)經(jīng)驗,他也身體力行的參與到許多企業(yè)的持續(xù)交付流程優(yōu)化過程中,這些經(jīng)驗都讓他能夠從更全面的視角來分析持續(xù)交付的問題。在這本書中介紹了許多直接拿來就可以使用的管理方法、項目案例、工具,能夠讓有需求在該領(lǐng)域有所作為的開發(fā)者帶來不少思考。
實質(zhì)上對于一家要實踐持續(xù)集成/持續(xù)交付的企業(yè)來說,將工具搭建完成并非核心難點,難點依然在于如何使用敏捷項目管理的思想,實現(xiàn)軟件的細(xì)粒度任務(wù)拆分,并能夠?qū)蝹€任務(wù)進行更好的測試,或許TDD是一種不錯的模式,但是卻可能給開發(fā)者的基礎(chǔ)技能提出了更高的要求,這將導(dǎo)致TDD無法落地。
如何快速驗證產(chǎn)品需求?在《持續(xù)交付2.0》中提出的了一系列的方法,例如裝飾窗、最小可行特性法、特區(qū)法、定向搜索法、稻草人法、、最小可行產(chǎn)品法等六種方法,通過建立快速驗證模型,提高軟件從需求到實現(xiàn)的整個流程,能夠為企業(yè)帶來不少便利。
而在研發(fā)階段,可以采用特性分支和特性開關(guān)的手法,利用git源代碼管理工具分支的妙處,將需求和代碼有機的耦合在一起,同時又依托項目管理工具,實現(xiàn)從需求=》實現(xiàn)=》發(fā)布的完整閉環(huán),從而為需求的驗證提供了雙保險;特性開關(guān)我最早在劉華老師的《獵豹行動-敏捷轉(zhuǎn)型》一書中看到,通過使用軟開關(guān)的形式,避免未開發(fā)完成的提前上線造成巨大的風(fēng)險,而在這邊書中也同樣提到了這樣的方法。在.NET中同樣也可以使用特性分支組件,后期我將嘗試一下。
而對于如何減少等待期,作者提到的方法是:
1、通過“拉動”讓價值流動起來,例如,如果是一個生產(chǎn)線的滯留,通過擴大瓶頸的處理能力,讓更多的需求能夠快速交付,這種手法看似能夠臨時提高環(huán)節(jié)處理能力,保障團隊的產(chǎn)出,但是顯然不是個良好的措施,更合理的措施就是根據(jù)下游的生產(chǎn)能力來確定上游的處理能力,由下游來拉動上游的需求。這客觀上要求將任務(wù)和需求的粒度進一步均勻化,將需求劃分成更加易于執(zhí)行、工作量類似的小需求,使得開發(fā)過程更加平滑。
2、任務(wù)自助化:也就是讓團隊掌握某些通用技能,以便在其他人員阻塞時,能夠同步完成相關(guān)任務(wù),避免了某些關(guān)鍵任務(wù)阻塞造成了整體流程的滯后。
在此我就不過多描述書中的精華了,有興趣的可以入手一本,絕對物超所值。
2、總體流程和環(huán)境部署
接下來我將進入本文的主題,首先我將構(gòu)建一個簡單的企業(yè)級持續(xù)集成/持續(xù)交付的管理流程,然后再對流程的實現(xiàn)過程進行較為詳細(xì)的介紹。
流程圖
[圖片](
)
在這個流程中,使用了master/dev的分支模式。
1、對于dev分支提交的代碼,經(jīng)過代碼編輯、靜態(tài)代碼掃描、自動化單元測試的流程,在運行通過后,有測試人員進行代碼的測試,并在代碼測試通過后,通過pull request提交給master分支的審查人員進行代碼檢查和合并。
2、測試人員對dev提交的代碼進行確認(rèn),并由master分支代碼審查人員進行代碼審查,通過后對代碼進行確認(rèn),并生成用于發(fā)布的生成包。
涉及的組件和說明
在流程中,使用了以下工具,依次安裝即可。
1、安裝OpenJDK
2、安裝Jenkins和相關(guān)插件
3、安裝PostgresDb
4、安裝SonarQube
5、安裝dotnetsdk3.1
6、安裝git
7、安裝nexus包管理器 for windows版用以實現(xiàn)包管理。
8、安裝Qy Wechat Notification或HTTP Request 用以實現(xiàn)企業(yè)微信提醒。
好吧,環(huán)境安裝就不介紹了。。
安裝補充說明
1、其中jenkins安裝的版本為2.190.3,OpenJDK安裝的版本為openjdk12.0。安裝完jenkins和openjdk后,需要進行環(huán)境變量的設(shè)置。
2、SonarQube安裝的版本為7.9.1,根據(jù)官方網(wǎng)站的說明,推薦使用的數(shù)據(jù)庫包括:sqlserver\oracle\postgresdb,在7.9.1和更高版本中,已經(jīng)不再推薦使用mysql。
3、SonarQube默認(rèn)使用了基于H2內(nèi)存數(shù)據(jù)庫的嵌入式數(shù)據(jù)庫,可以在測試環(huán)境下使用,但是不建議用于生產(chǎn)環(huán)境。
5、安裝完sonarqube、和數(shù)據(jù)庫后,需要修改sonarqube/conf/sonar.properties文件中的數(shù)據(jù)庫配置地址,并將sonarqube的服務(wù)重啟。
[圖片](?
)
在windows系統(tǒng)中,點擊sonarqube-xxx\bin\windows-x86-64文件夾中的InstallNTService.bat用以安裝SonarQube的服務(wù),而StartNTService.bat則用于啟動SonarQube的應(yīng)用服務(wù)。如果數(shù)據(jù)庫配置失敗,則SonarQube會啟動失敗,并提示以下錯誤:
[sonar-1510653879773] exception caught on transport layer [[id: 0x346b46fb, /127.0.0.1:59330 => /127.0.0.1:9001]], closing connection
java.io.IOException: An existing connection was forcibly closed by the remote host
6、由于使用了自行搭建的Nuget包源管理器,所以在進行構(gòu)建時,會提示錯誤,jenkins會使用
Jenkins的項目類型
在jenkins中提供了自由風(fēng)格、單流水線、多分支流水線、多配置項目等不同類型的項目,可以根據(jù)實際情況進行取舍,在本人的嘗試過程中,分別總結(jié)了三種不同類型的項目可適用的場景:
自由風(fēng)格項目
操作流程簡單,無需配置groovy腳本,即可簡單的完成項目的自動化構(gòu)建。
在自由風(fēng)格模式的項目中,實現(xiàn)代碼編譯的過程主要在構(gòu)建窗口中,主要使用dotnet -相關(guān)命令來完成。包括:
1、dotnet restore 還原依賴包。
2、dotnet build 編譯
3、dotnet publish -o ./bin/release 發(fā)布到指定目錄下。
4、如果需要使用sonarqube來進行靜態(tài)代碼檢查,需要在服務(wù)器上安裝dotnet-sonarscanner組件,這個組件是基于.net core構(gòu)建的靜態(tài)代碼檢查組件,安裝的命令為:
dotnet tool install --global dotnet-sonarscanner --version 4.8.0;
5、如果采用.net framework 傳統(tǒng)框架,則可以繼續(xù)使用原來的SonarScanner.MSBuild.exe組件進行代碼檢查結(jié)果的上傳。
6、如果需要在自由風(fēng)格項目中使用powershell腳本,可以在jenkins=》插件管理=》可用插件中搜索powershell即可。
單流水線項目
單流水線項目:可適用于只有一個分支和一套環(huán)境需要部署時的項目構(gòu)建,其發(fā)布流程需要使用groovy腳本來實現(xiàn)。點擊查看pipeline的語法
1、在流水線項目中,都在項目文件的根目錄中添加jenkinsfile文件(無擴展名)作為jenkins編譯時的腳本文件,而這個文件的腳本語法采用groovy語言,并支持開發(fā)者按照腳本語言進行擴展。
2、在單流水線項目中不支持groovy的分支判斷條件,支持邏輯比較簡單的腳本。
3、與編譯有關(guān)的結(jié)構(gòu)均寫在jenkinsfile中,因此jenkins的UI界面可以理解為配置與項目相關(guān)的環(huán)境變量信息。
4、可以在jenkinsfile中定義輸入的參數(shù),例如:
parameters{
? ? ? ? string(name:'ProjectName', defaultValue: 'Enter Your ProjectName', description: 'Enter your project name here')
? ? ? ? string(name:'Contact', defaultValue: '"@All","xxx"', description: 'Enter Your Contract')?
? ? ? ? string(name:'RepoUrl', defaultValue: 'https://xxx.com/xxx/xxx.git', description: ' gitee代碼路徑')
}
在jenkins界面中,可以顯示成
[圖片](?
)
在具體場景下就可以通過jenkins界面?zhèn)魅胂嚓P(guān)參數(shù)進行編譯的測試了。
多流水線項目
多分支流水線項目:使用于一個倉庫下各分支不同環(huán)境需要部署時的項目構(gòu)建,其發(fā)布流程也需要使用groovy腳本實現(xiàn)。
1、多流水線項目支持使用分支判斷條件的語法,因此可以使用的場景更多。
2、其他的總體上和單分支流水線差不多,此處就不在贅述了。
以下編寫了一個簡單的示例,僅供參考。
pipeline{agent any?parameters{string(name:'Contact', defaultValue: '"@All",""', description: 'Enter Your Contract')?string(name:'RepoUrl', defaultValue: '', description: ' 代碼路徑')string(name:'SonarUrl', defaultValue: 'http://xxx:9000', description: ' sonar代碼路徑')}?stages {stage('When Master') {?when {expression {BRANCH_NAME==~/(master)/}}?steps{? ? ? ?checkout([$class: 'GitSCM', branches: [[name: '*/master']], doGenerateSubmoduleConfigurations: false, extensions: [], submoduleCfg: [], userRemoteConfigs: [[credentialsId: 'xxx', url: params.RepoUrl]]])}}stage ("When Dev"){when {branch 'dev'}?steps{ rojectName}")?}}?stage("test"){when{expression{return true}}steps{echo "OK"}}? ??stage('Web Dev Build') {steps{}}?}post{success{SendToWeChatWork("CI Task success,ProjectName is ${params.ProjectName}")?echo 'Publish Success'}failure{SendToWeChatWork("CI Task Failure,ProjectName is ${params.ProjectName}")?echo 'Publish Failure'}} } def SendToWeChatWork(content) {? ? }多配置項目
如果組件代碼需要在不同的配置、不同的環(huán)境下重復(fù)部署,其基本邏輯類似,只是配置不同,就可以使用多配置項目。
好吧,我就沒有嘗試了,因為我已經(jīng)用了多流水線項目來實現(xiàn)了。在這篇示例中對多配置項目有比較詳細(xì)的用法,需要可自取。
總結(jié)
將企業(yè)級持續(xù)集成的環(huán)境搭建起來本身并不難,難的是如何將整套體系與公司現(xiàn)有的開發(fā)流程相結(jié)合,考慮到受康威定律的影響,不同的組織對于新事物的接受程度總是不同的,所以難免需要做一些準(zhǔn)備。
好文要頂?關(guān)注我?收藏該文??
總結(jié)
以上是生活随笔為你收集整理的基于Jenkins的持续交付全流程设计与实践的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Asp.Net Core下的开源任务调度
- 下一篇: Beetlex之redis驱动