<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          豬八戒網(wǎng)CI/CD最佳實(shí)踐之路

          共 5328字,需瀏覽 11分鐘

           ·

          2021-07-30 17:09


          序言


          本文旨在介紹ZBJ DevOps團(tuán)隊(duì)傾力打造的DevOps平臺(tái)中關(guān)于CI/CD流水線部分的實(shí)踐。歷經(jīng)三次大版本迭代更新的流水線,完美切合ZBJ各種業(yè)務(wù)發(fā)展需求,在滿足高頻率交付的同時(shí),提高了研發(fā)效率,降低了研發(fā)成本,保證了交付質(zhì)量。

          持續(xù)集成(Continuous Integration)簡(jiǎn)稱CI,持續(xù)集成強(qiáng)調(diào)開發(fā)人員提交了新代碼之后,立刻進(jìn)行構(gòu)建、(單元)測(cè)試。根據(jù)結(jié)果,我們可以確定新代碼和原有代碼能否正確地集成在一起。持續(xù)集成過程中很重視自動(dòng)化測(cè)試驗(yàn)證結(jié)果,對(duì)可能出現(xiàn)的一些問題進(jìn)行預(yù)警,以保障最終集成的代碼沒有問題。持續(xù)交付(Continuous Delivery)簡(jiǎn)稱CD,持續(xù)交付在持續(xù)集成的基礎(chǔ)上,將集成后的代碼部署到更貼近真實(shí)運(yùn)行環(huán)境的「類生產(chǎn)環(huán)境」(test,testing)中,然后交付給質(zhì)量團(tuán)隊(duì),以供評(píng)審。如果評(píng)審?fù)ㄟ^,代碼就進(jìn)入生產(chǎn)階段。持續(xù)交付并不是指軟件每一個(gè)改動(dòng)都要盡快部署到產(chǎn)品環(huán)境中,它指的是任何的代碼修改都可以在任何時(shí)候?qū)嵤┎渴?。有的人也把CD稱為Continuous Deployment(持續(xù)部署),持續(xù)部署是指當(dāng)交付的代碼通過評(píng)審之后,可以部署到生產(chǎn)環(huán)境中。這里需要注意的是,持續(xù)部署應(yīng)該是持續(xù)交付的最高階段,持續(xù)交付是一種能力,持續(xù)部署是一種持續(xù)交付的表現(xiàn)方式。

          CI/CD過程示意圖


          豬八戒網(wǎng)的CI/CD之路


          背景介紹

          在提到ZBJ DevOps流水線之前,先交代一下歷史背景。2015年前,豬八戒網(wǎng)80%的項(xiàng)目都是用PHP語(yǔ)言開發(fā)的,剩下的少部分使用的是Nodejs和Java。2015年,ZBJ研發(fā)中心進(jìn)行了自發(fā)性的“工業(yè)革命”——騰云七號(hào)行動(dòng)——使用Java語(yǔ)言將核心業(yè)務(wù)代碼進(jìn)行了重構(gòu)和拆解,建立了以Dubbo為核心的SOA微服務(wù)框架,使用ZooKeeper+Swoole為核心的業(yè)務(wù)調(diào)用提供機(jī)制。滿足新業(yè)務(wù)使用Java語(yǔ)言編寫、老業(yè)務(wù)仍然使用PHP編寫,同時(shí)支持兩種語(yǔ)言(Nodejs&PHP)調(diào)用Dubbo服務(wù)的能力。


          之后,開始全面推行前后端分離,于是流行了沿用至今的主流架構(gòu):

          • Nodejs:負(fù)責(zé)前端

          • Java:負(fù)責(zé)后端

          • PHP:負(fù)責(zé)老項(xiàng)目維護(hù)


          剩余部分小系統(tǒng)或者邊緣化的工具使用其他語(yǔ)言開發(fā),或者在此三種語(yǔ)言基礎(chǔ)上的一些變種:


          隨著業(yè)務(wù)的重構(gòu)和拆解,以前一個(gè)個(gè)龐大的系統(tǒng)被拆解成若干個(gè)獨(dú)立的小系統(tǒng),使得交付變得更加容易。


          而隨著項(xiàng)目工程數(shù)量的快速增長(zhǎng),交付開始變得頻繁,傳統(tǒng)開發(fā)模式的一兩個(gè)月交付一次遠(yuǎn)遠(yuǎn)不能滿足交付要求,改變迫在眉睫。

          2016年Q3季度,感受到改變迫在眉睫,ZBJ研發(fā)中心經(jīng)充分準(zhǔn)備后決定抽調(diào)部分運(yùn)維同學(xué)和開發(fā)同學(xué)組建一支名為“DevOps取經(jīng)團(tuán)”的團(tuán)隊(duì),力圖打造屬于ZBJ自己的以提高研發(fā)效率為目標(biāo)的平臺(tái)。

          ZBJ CI/CD發(fā)展史

          第一階段:2015年以前

          2015年以前,此時(shí)“工業(yè)革命”還未開始,ZBJ所謂的流水線先后經(jīng)歷了“大鍋飯年代”、“公交車模式”。

          大鍋飯年代(本圖由DevOps團(tuán)隊(duì)提供)

          公交車模式(本圖由DevOps團(tuán)隊(duì)提供)


          可以看到,無論是“大鍋飯年代”,還是“公交車模式”都會(huì)面臨很多問題:

          • 項(xiàng)目耦合度太高,容易導(dǎo)致合并沖突,環(huán)境沖突等。

          • 集成過程中未對(duì)代碼進(jìn)行審查,錯(cuò)誤代碼發(fā)布到測(cè)試環(huán)境后,會(huì)影響依賴方的測(cè)試。

          • 發(fā)布受限制,必須在專門時(shí)間由專人發(fā)布。

          • 發(fā)布異常時(shí),回滾工作異常艱難。


          第二階段(2016-2017):私家車模式

          通過“工業(yè)革命”的變革,對(duì)系統(tǒng)的重構(gòu)和拆解,同時(shí)引入工程責(zé)任制,給每個(gè)工程指定負(fù)責(zé)人,對(duì)工程的各種權(quán)限進(jìn)行了管控,業(yè)務(wù)范圍和邊界變得更加清晰,使得項(xiàng)目耦合度太高的問題得到了很大的緩解。

          解決了項(xiàng)目耦合度高的問題,接下來解決如何實(shí)現(xiàn)隨時(shí)由開發(fā)團(tuán)隊(duì)自主發(fā)代碼的問題。

          用Jira做研發(fā)流程管理,制定針對(duì)ZBJ需求上線的流程:


          需求上線流程每個(gè)環(huán)節(jié)對(duì)應(yīng)流水線的每個(gè)環(huán)境,只有到達(dá)某個(gè)環(huán)節(jié),才能推送對(duì)應(yīng)環(huán)境,每個(gè)環(huán)節(jié)會(huì)制定對(duì)應(yīng)的準(zhǔn)入準(zhǔn)出,保證每走到的下一步都離成功部署更近一步。

          推送環(huán)境示意圖

          每個(gè)環(huán)境制定不一樣的執(zhí)行任務(wù),基本包括Jira狀態(tài)校驗(yàn),代碼審查(單元測(cè)試),編譯構(gòu)建,上傳包到制品庫(kù),拉取制品庫(kù)中的包部署到對(duì)應(yīng)環(huán)境。

          值得注意的是,我們引入了Docker發(fā)布,所以我們的流水線是支持容器和虛擬機(jī)的混合發(fā)布的。虛擬機(jī)發(fā)布方式的制品是存放在一個(gè)叫做文件服務(wù)器的地方,容器發(fā)布方式的制品是push到Harbor倉(cāng)庫(kù)的。

          容器發(fā)布&虛擬機(jī)構(gòu)建打包示意圖

          采用的分支策略是:branches開發(fā),master發(fā)布,tags存檔(我們使用GitLab作為源碼管理工具)。在測(cè)試環(huán)境通常為非master分支,測(cè)試完畢后合并到master,推送預(yù)發(fā)布,并針對(duì)當(dāng)前版本打一個(gè)tag。針對(duì)這種情況,我們的“一次構(gòu)建,處處使用”指的是測(cè)試環(huán)境用測(cè)試環(huán)境構(gòu)建好的包,其他環(huán)境用預(yù)發(fā)布構(gòu)建好的包。

          各環(huán)境使用制品示意圖

          在推送每一個(gè)環(huán)境(test環(huán)境除外)時(shí),都會(huì)校驗(yàn)當(dāng)前版本的代碼是否為前置環(huán)境推送過的最新代碼,保證不會(huì)將沒有經(jīng)過審查的代碼交付到線上。

          在測(cè)試環(huán)境每一次編譯構(gòu)建之前,都會(huì)對(duì)代碼進(jìn)行一次安全掃描,Java語(yǔ)言的工程通過解析pom文件對(duì)其所有的依賴進(jìn)行遞歸掃描,Nodejs語(yǔ)言的工程通過對(duì)node_module里下載的包進(jìn)行遞歸掃描,確保有安全漏洞的代碼不會(huì)被帶入到生產(chǎn)環(huán)境。

          編譯構(gòu)建時(shí),會(huì)根據(jù)開發(fā)語(yǔ)言的不同,執(zhí)行不同的編譯腳本,根據(jù)發(fā)布方式的不同(虛擬機(jī)發(fā)布或者容器發(fā)布),執(zhí)行不一樣的后續(xù)操作步驟。

          我們將Jenkins作為后臺(tái)編譯服務(wù)器,采用的是多master多slave的架構(gòu),我們并未直接使用Jenkins的流水線,而是開發(fā)了一個(gè)叫Pipeline的系統(tǒng),與Jenkins做對(duì)接(此時(shí)的對(duì)接方式是調(diào)用Jenkins的API),由Pipeline系統(tǒng)提供Jenkins作業(yè)所需要的全部信息,另外編寫了整個(gè)過程需要具體執(zhí)行操作的腳本,通過Jenkins的job配置“Execute shell”的方式每次在構(gòu)建之前導(dǎo)入到工作空間。


          流水線標(biāo)準(zhǔn)生產(chǎn)過程大體如下:

          流水線標(biāo)準(zhǔn)生產(chǎn)過程示意圖

          另外,針對(duì)回滾的情況,因?yàn)槊看卧谏暇€前都會(huì)在預(yù)發(fā)布會(huì)構(gòu)建一個(gè)穩(wěn)定的版本,并打一個(gè)tag,并且記錄下tag對(duì)應(yīng)的制品(包或者鏡像)版本,所以在回滾的時(shí)候,只要選擇要回滾的版本,便能找到對(duì)應(yīng)版本的制品,進(jìn)行重新發(fā)布,以此達(dá)到回滾的目的。

          回滾流程

          至此,第二階段大體實(shí)現(xiàn)了以下功能:

          • 通過用Jira需求上線流程和流水線做整合,以及多種推送前的校驗(yàn),保證了上線過程的每一步都是可靠的

          • 每一個(gè)環(huán)境的集成和發(fā)布都是自動(dòng)化的

          • 因?yàn)檫^程變得可靠且自動(dòng)化,使得將發(fā)布過程開放給研發(fā)團(tuán)隊(duì)成為了可能,達(dá)到了隨時(shí)自主上線的目的。


          然而這樣的流水線也有諸多問題:

          • 不夠靈活,如在推送測(cè)試環(huán)境時(shí),整個(gè)過程執(zhí)行的步驟是固定的的,即第一步做什么,第二步做什么都是固定的,不能新增也不能刪減,如某些團(tuán)隊(duì)需要進(jìn)行單元測(cè)試,有的不需要,但流水線都會(huì)去執(zhí)行單元測(cè)試,通常情況下單元測(cè)試過程是一個(gè)花費(fèi)時(shí)間比較長(zhǎng)的過程,這對(duì)于需要頻繁更改和部署的業(yè)務(wù)是不友好的。

          • 推送成功率不高,因?yàn)檎麄€(gè)過程是串聯(lián)的,某一個(gè)環(huán)節(jié)出現(xiàn)錯(cuò)誤,將會(huì)導(dǎo)致本次推送失敗,而某些環(huán)節(jié)本不應(yīng)該影響構(gòu)建結(jié)果的,最后導(dǎo)致了構(gòu)建失敗。


          第三階段(2017-2019):擁有靈活車道的私家車模式

          考慮到前面提到的兩點(diǎn),ZBJ DevOps團(tuán)隊(duì)在17年底對(duì)流水線做了二次改造:

          1、所有執(zhí)行步驟拆解成獨(dú)立原子任務(wù),建立原子任務(wù)庫(kù);

          2、將原子任務(wù)根據(jù)功能性分為兩種,校驗(yàn)類以及執(zhí)行類,校驗(yàn)類原子任務(wù)主要是是做準(zhǔn)入準(zhǔn)出的判斷,執(zhí)行類主要是編譯構(gòu)建,打鏡像,上傳hub倉(cāng)庫(kù)以及部署。

          3、將原子任務(wù)根據(jù)執(zhí)行載體分為兩種,Java類和Jenkins類,直接用Java程序執(zhí)行的任務(wù)為Java類,需要Jenkins執(zhí)行的任務(wù)為Jenkins類。

          4、根據(jù)開發(fā)語(yǔ)言、發(fā)布方式、業(yè)務(wù)類型的不同,從原子任務(wù)庫(kù)中選取不同原子任務(wù)組成一條標(biāo)準(zhǔn)有序的執(zhí)行流水線。

          5、提供工程特殊配置,如有些工程需要增強(qiáng)校驗(yàn),有的工程需要減少校驗(yàn),則可以通過啟用和禁用的方式進(jìn)行特殊配置,如下圖所示,根據(jù)1、2和3步驟后可最終生成一條本次執(zhí)行的流水線任務(wù)列表。

          原子任務(wù)一覽表

          執(zhí)行效果圖

          6、根據(jù)原子任務(wù)的制定,我們將Jenkins執(zhí)行的job也拆分成了對(duì)應(yīng)的幾類,每一類擁有足夠多數(shù)量的job進(jìn)行任務(wù)的執(zhí)行。



          7、升級(jí)了Pieline系統(tǒng)和Jenkins通信架構(gòu),通過編寫一個(gè)RabbitMQ的插件植入到Jenkins Master上,從原來調(diào)用API的方式,改成用RabbitMQ的方式進(jìn)行通信,大大提高了效率和成功率。

          通信示意圖

          8、升級(jí)了Jenkins架構(gòu),構(gòu)建一個(gè)能適配ZBJ所有開發(fā)語(yǔ)言的鏡像,利用Jenkins Master的Kubernetes插件,將原來的虛擬機(jī)slave節(jié)點(diǎn)全部替換成容器slave節(jié)點(diǎn),并且這個(gè)slave集群完全由Jenkins Master的Kubernetes插件調(diào)度,不論在高并發(fā)和低并發(fā)的時(shí)候都能及時(shí)擴(kuò)縮容,滿足業(yè)務(wù)需求。

          第四階段(2020-至今):智能駕駛模式

          可以看到,到第三個(gè)階段為止,我們的每一次編譯過程,都需要研發(fā)同學(xué)“推送一下”,而且這個(gè)過程也是需要花費(fèi)一些時(shí)間的,比如一個(gè)正常的Nodejs工程平均編譯時(shí)長(zhǎng)至少需要花費(fèi)100+s以上,一個(gè)正常的Java工程平均編譯時(shí)長(zhǎng)至少也是需要30s以上,由于我們提供了推送過程“可視化”的功能,且沒有執(zhí)行結(jié)果的通知,導(dǎo)致用戶必須關(guān)注推送過程以確保本次推送是成功的,大大浪費(fèi)了研發(fā)同學(xué)的時(shí)間。

          在此基礎(chǔ)上,我們進(jìn)一步做出了以下優(yōu)化:

          1、為每一個(gè)GitLab上的工程添加一個(gè)Webhook,每當(dāng)開發(fā)人員向倉(cāng)庫(kù)push一次,便會(huì)觸發(fā)Webhook,調(diào)用Pipeline系統(tǒng)接口進(jìn)行一次快速構(gòu)建。


          注意:并不是每次push都會(huì)進(jìn)行一次快速構(gòu)建,為了防止開發(fā)同學(xué)頻繁修改少量代碼提交到版本庫(kù),我們規(guī)定了一個(gè)“暗號(hào)”,只有當(dāng)開發(fā)同學(xué)在commit message中添加這個(gè)“暗號(hào)”,才會(huì)觸發(fā)一次快速構(gòu)建。

          auto_trigger_build就是暗號(hào)內(nèi)容


          2、快速構(gòu)建的結(jié)果是構(gòu)建一個(gè)包或者一個(gè)鏡像,存放在前文提到過的文件服務(wù)器或者Harbor倉(cāng)庫(kù)。在下一次用戶“推送”的時(shí)候,便會(huì)根據(jù)分支和版本判斷是否存在已編譯過的包或者鏡像,如果存在,則直接使用,跳過編譯過程。


          3、增加快速構(gòu)建結(jié)果通知,因?yàn)檎麄€(gè)快速構(gòu)建過程是后臺(tái)執(zhí)行的,所以流水線系統(tǒng)通過企業(yè)微信的方式通知到用戶本次快速構(gòu)建的結(jié)果。

          快速構(gòu)建前通知

          快速構(gòu)建完成后結(jié)果通知

          4、除了增加快速構(gòu)建的通知,我們還增加了推送的通知。用戶再也不用關(guān)注推送過程,只需要在推送后繼續(xù)做其他事情,推送結(jié)果由企業(yè)微信通知到用戶。



          值得注意的是,當(dāng)推送失敗后,流水線系統(tǒng)也會(huì)通知到用戶,進(jìn)行對(duì)應(yīng)問題的排查。


          至此,ZBJ的CI/CD實(shí)踐之路基本介紹完畢,當(dāng)然,其中也還有很多細(xì)節(jié)方面,因?yàn)樯婕暗臇|西太多,不便鋪開來講。


          總結(jié)三次重大改造的結(jié)果


          第一次改造:奠定了ZBJ的CI/CD基礎(chǔ),打造了一條標(biāo)準(zhǔn)的流水線,解放了運(yùn)維勞動(dòng)力(過程全自動(dòng)化),提高了研發(fā)效率,降低了研發(fā)成本(運(yùn)維同學(xué)由最多時(shí)候的三四十個(gè)減少到了不到十個(gè)人)。

          第二次改造:流水線實(shí)現(xiàn)了高可用,同時(shí)其靈活的配置能完美滿足不同業(yè)務(wù)團(tuán)隊(duì)的需求。

          第三次改造:提升了流水線效率,弱化推送過程,增強(qiáng)以人為本的體驗(yàn),使推送過程更加智能化。


          談?wù)勎磥?/section>


          CI/CD實(shí)踐之路還在繼續(xù),因?yàn)椴煌居胁煌臉I(yè)務(wù)場(chǎng)景,而同一公司的業(yè)務(wù)也會(huì)隨著時(shí)代的發(fā)展不斷變化,只有適合自己的才是最好的,只有能擁抱變化的才是最好的,但萬變不離其宗的,我覺得應(yīng)該有一下幾點(diǎn):

          • CI/CD應(yīng)該是以提高研發(fā)效率為目標(biāo)的實(shí)踐,一切脫離這個(gè)目標(biāo)只是為了迎合什么口號(hào)而做什么的是都是耍牛氓。而實(shí)現(xiàn)這個(gè)目標(biāo)是一個(gè)比較漫長(zhǎng)的過程,一開始會(huì)比較容易,后面就會(huì)越來越難,這需要不斷思考和學(xué)習(xí)的過程。

          • CI/CD應(yīng)該是緊貼業(yè)務(wù)的,因?yàn)闃I(yè)務(wù)的不同,要求的技術(shù)架構(gòu)也會(huì)有所不同,隨之而來,要求的交付方式也會(huì)有所不同。

          • CI/CD應(yīng)該是以人為本的,我們應(yīng)該盡可能地將一切繁瑣的過程交給程序去執(zhí)行,而人只需要“坐享其成”或者做少量的決策即可。


          文章來源:八戒技術(shù)團(tuán)隊(duì),點(diǎn)擊查看原文。

          推薦閱讀:

          世界的真實(shí)格局分析,地球人類社會(huì)底層運(yùn)行原理

          不是你需要中臺(tái),而是一名合格的架構(gòu)師(附各大廠中臺(tái)建設(shè)PPT)

          企業(yè)IT技術(shù)架構(gòu)規(guī)劃方案

          論數(shù)字化轉(zhuǎn)型——轉(zhuǎn)什么,如何轉(zhuǎn)?

          華為干部與人才發(fā)展手冊(cè)(附PPT)

          企業(yè)10大管理流程圖,數(shù)字化轉(zhuǎn)型從業(yè)者必備!

          【中臺(tái)實(shí)踐】華為大數(shù)據(jù)中臺(tái)架構(gòu)分享.pdf

          華為的數(shù)字化轉(zhuǎn)型方法論

          華為如何實(shí)施數(shù)字化轉(zhuǎn)型(附PPT)

          超詳細(xì)280頁(yè)Docker實(shí)戰(zhàn)文檔!開放下載

          華為大數(shù)據(jù)解決方案(PPT)


          瀏覽 64
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  热久色| 91AV视频在线观看 | 亚洲成人视频在线观看 | 89bbbb在线播放 | 国产69久久久 |