賴正華
(中移信息技術(shù)有限公司,廣東 深圳 518048)
現(xiàn)在很多的業(yè)務(wù)系統(tǒng)引用微服務(wù)化的思想,將業(yè)務(wù)系統(tǒng)的功能在應(yīng)用程序?qū)崿F(xiàn)上進(jìn)行解耦處理:每個功能由單獨的程序模塊來提供,再將各個程序模塊,利用消息隊列的形式串聯(lián)起來。假如應(yīng)用程序分為了前置程序、業(yè)務(wù)處理程序。前置程序接受請求后,通過MQ消息中間件將消息通過點對點的方式分發(fā)到業(yè)務(wù)處理程序。業(yè)務(wù)處理程序根據(jù)不同的請求渠道以及用戶歸屬省等因素,可將消息引流到不同的業(yè)務(wù)處理程序去消費消息,比如對業(yè)務(wù)量很大的省份或者渠道,由A主機(jī)單獨提供服務(wù),對業(yè)務(wù)量小的省份或者渠道可以多個省或渠道共享一臺主機(jī)消費消息,利用MQ的點對點消息,實現(xiàn)了流量的分流。因此,在代碼打包編譯時,需要對不同的業(yè)務(wù)處理節(jié)點標(biāo)識不同的appcode,每一個tomcat運行單獨標(biāo)識appcode的業(yè)務(wù)處理war包程序,這樣便可實現(xiàn)點對點消息消費。由于承載的是全網(wǎng)的業(yè)務(wù),部署的服務(wù)器數(shù)量和tomcat容器數(shù)量會達(dá)到數(shù)十個,且隨著業(yè)務(wù)規(guī)模的發(fā)展,服務(wù)器的數(shù)量一直在增長,因此在每次進(jìn)行變更上線時,運維人員的工作強(qiáng)度和壓力越來越大。且系統(tǒng)屬于實時交易類系統(tǒng),為在全球漫游的用戶提供無間斷的服務(wù),對系統(tǒng)變更上線提出了高要求:需要不間斷提供服務(wù)且快速又準(zhǔn)確地完成變更上線操作。本文將對這種業(yè)務(wù)場景的系統(tǒng)上線方式展開研究。
目前行業(yè)內(nèi)用于自動化上線的開源工具有Ansible、Saltstack、Jenkins等。
Ansible是一種基于Paramiko開發(fā)的自動化運維工具。通過SSH協(xié)議與遠(yuǎn)程主機(jī)相結(jié)合,并以模塊化的方式實現(xiàn)批量部署、自動化執(zhí)行命令等功能。基于Ansible可以實現(xiàn)批量的操作,比如對批量的tomcat進(jìn)行停啟操作,對批量的tomcat下的webapp目錄替換相同的war包程序,但Ansible不適合這種業(yè)務(wù)場景:系統(tǒng)涉及有數(shù)十個tomcat節(jié)點,每個節(jié)點運行的war包程序不同,因此Ansible工具無法實現(xiàn)對這數(shù)十個運行不同war程序的tomcat進(jìn)行批量的操作。
Saltstack也是類似的情況,只能對相同的命令執(zhí)行批量操作,不適合這種不同主機(jī)的操作命令不同、變更上線的程序版本不同且涉及的主機(jī)數(shù)量眾多的業(yè)務(wù)場景。
Jenkins是一款開源CI&CD軟件,用于自動化各種任務(wù),包括構(gòu)建、測試和部署軟件[1]。本文基于Jenkins的Publish Over SSH插件實現(xiàn)將上線程序從Jenkins服務(wù)器分發(fā)到應(yīng)用主機(jī),并執(zhí)行shell腳本實現(xiàn)變更上線的流水線操作:應(yīng)用程序備份、停tomcat進(jìn)程、刪原來的程序文件、移新版本程序文件到指定目錄、更改配置文件、啟動tomcat進(jìn)程、檢查進(jìn)程是否啟動等操作。
本文將基于Jenkins設(shè)計一種方案,可實現(xiàn)實時交易系統(tǒng)的不中斷上線。首先,若需要實現(xiàn)業(yè)務(wù)系統(tǒng)的不中斷上線,需要對業(yè)務(wù)系統(tǒng)的部署進(jìn)行重新設(shè)計,原來的業(yè)務(wù)系統(tǒng)由前置程序?qū)懴⒌较㈥犃兄?,業(yè)務(wù)處理節(jié)點從MQ服務(wù)器監(jiān)聽并拉取消息處理,而且是采用點對點的消息隊列模式,如果未采用主備的模式部署,那么在變更上線時,需要重啟tomcat操作,消息沒有消費者來消費,此時會導(dǎo)致業(yè)務(wù)中斷?,F(xiàn)在改為部署主備式的業(yè)務(wù)處理,打包編譯時,對war包加上標(biāo)簽appcodeA和appcodeB,兩個業(yè)務(wù)處理節(jié)點都監(jiān)控消息隊列A,都可以從這個隊列拉取消息處理,兩個tomcat都可以監(jiān)聽這個消息隊列A,實行搶消息的方式去消費消息。其他的業(yè)務(wù)處理節(jié)點也做類似的部署調(diào)整,這樣業(yè)務(wù)系統(tǒng)在MQ的作用下,實現(xiàn)了分布式的部署,且每個業(yè)務(wù)處理、前置程序都具備了主備節(jié)點,如圖1所示。這樣在日常的變更操作時,如果對主節(jié)點進(jìn)行重啟操作的時候,消息隊列A的消息可以被備tomcat節(jié)點進(jìn)行消費,正常提供對外訪問,實現(xiàn)業(yè)務(wù)不中斷。但隨之帶來的是tomcat數(shù)量的翻倍。
圖1 業(yè)務(wù)應(yīng)用分布式化部署
在對應(yīng)用系統(tǒng)進(jìn)行了部署優(yōu)化后,在Jenkins管理界面,添加遠(yuǎn)程主機(jī);然后對每一個tomcat配置一個job任務(wù),在job任務(wù)的配置界面編寫遠(yuǎn)程執(zhí)行的shell命令。按照上線操作的流水操作編寫shell命令。當(dāng)觸發(fā)這個任務(wù)時,能單獨完成這個tomcat節(jié)點的進(jìn)程啟停、文件備份與換新等操作。
在對所有的主節(jié)點配置完成job任務(wù)后,將所有的主節(jié)點job加入到一個新的job中,如圖2所示。
圖2 主備節(jié)點job列表
同理對所有的備節(jié)點,每個節(jié)點配置一個job任務(wù),在job任務(wù)中配置對應(yīng)的shell命令,實現(xiàn)各個節(jié)點可以個性化地操作tomcat。將所有的備節(jié)點job加入到新的一個job中,任命為BUSI-BACK,如圖2所示。這樣便可以將所有的主節(jié)點歸納到一個job,所有的備節(jié)點歸納到另一個job,可實現(xiàn)并發(fā)操作。
在上線變更操作時,依次對主節(jié)點的控制任務(wù)BUSIMAIN觸發(fā)工程構(gòu)建操作,如圖3所示,此時所有主節(jié)點的tomcat會并發(fā)的進(jìn)行上線操作,極大地縮短上線變更時間。此時,備節(jié)點的tomcat從消息隊列讀取消息進(jìn)行消息處理,對外表現(xiàn)為業(yè)務(wù)未中斷。在主節(jié)點完成上線變更操作后,再對備節(jié)點進(jìn)行工程構(gòu)建操作,此時主節(jié)點的所有tomcat從消息隊列拉取消息進(jìn)行業(yè)務(wù)處理,對外表現(xiàn)也是業(yè)務(wù)不中斷。
圖3 主備節(jié)點的控制job列表
首先在部署主機(jī)運行Jenkins服務(wù):nohup java-jar jenkins.war--httpPort=8080&。在瀏覽器輸入Jenkins的訪問界面:http://localhost:8080,按照提示輸入密鑰后即可進(jìn)入Jenkins服務(wù)的管理界面[2]。
Jenkins具有可伸縮的插件機(jī)制,集成人員可以很方便地進(jìn)行配置的自主性選擇,根據(jù)自己所需要的插件進(jìn)行安裝、刪除和添加。進(jìn)入到首界面的系統(tǒng)管理界面后,再進(jìn)入到插件管理界面,本文的方案需要安裝Publish Over SSH插件包,在生產(chǎn)環(huán)境需要采用離線安裝的方式[3]。
接下來是新建job的工作,即如圖2所示的BN-S-001即為一個獨立的job。在界面中進(jìn)行配置和shell命令編寫工作。在配置界面中,需要配置目標(biāo)主機(jī)的信息,即job的名稱,需要配置上線文件的source files的正則表達(dá)式,在本文中配置為*,即匹配任何的文件,本文中默認(rèn)所有的主節(jié)點命名為BN-S-00*,備節(jié)點則命名為BN-S-10*。在本文中將實現(xiàn)對一個tomcat進(jìn)行如下流水線式的操作:備份原webapps目錄下的程序文件、kill tomcat進(jìn)程、休眠一段時間待tomcat完成上一筆業(yè)務(wù)、再次kill tomcat進(jìn)程、刪除原webapps目錄下的所有war包程序和war包解壓后的程序文件、刪除配置文件、將要上線的新程序war包文件拷貝到webapps目錄下、拷貝新的配置文件到配置目錄下、啟動tomcat進(jìn)程。每一個tomcat都需要進(jìn)行類似的流水操作。
實現(xiàn)的shell腳本如下:
在每個job中都完成上述的job配置,以及把shell命令拷貝到每個job的command窗口中便可完成配置[4]。配置完成后的效果如圖2所示。
將所有的BN-S-00*開頭的job作為主節(jié)點編排在BUSIMAIN這個job中,將BN-S-10*開頭的job編排到BUSIBACK這個job中作為備節(jié)點。對BUSI-MAIN這個job點擊構(gòu)建操作,即可觸發(fā)這個job下的所有主節(jié)點job進(jìn)行并發(fā)的構(gòu)建,所有的job并發(fā)的執(zhí)行shell命令,完成流水線式的操作。在對BUSI-MAIN這個job完成構(gòu)建的時刻,tomcat是不提供對外服務(wù)的,此時作為備節(jié)點的BN-S-10*節(jié)點均正常對外提供服務(wù)。在BUSI-MAIN這個job完成構(gòu)建后,即完成了新版本上線后,再對BUSI-BACK這個job進(jìn)行相同的操作,此時主節(jié)點對外提供服務(wù),如圖4所示。經(jīng)過實測,單人對55個tomcat進(jìn)行正常的變更上線操作,需要花費的時間在2個小時以上,但利用本文的方案實現(xiàn),可在5分鐘內(nèi)完成上線工作,不中斷業(yè)務(wù)系統(tǒng)的服務(wù),且可大大降低人為錯誤操作的風(fēng)險。
圖4 測試結(jié)果
本文針對實時交易業(yè)務(wù)系統(tǒng)在進(jìn)行不中斷業(yè)務(wù)變更上線提出了一種解決方案。適用的業(yè)務(wù)場景為每個tomcat或者其他容器所承載的應(yīng)用程序版本不同,但又需要批量上線的情況。利用Jenkins可定制化地實現(xiàn)每個tomcat或容器實現(xiàn)不同的流水線操作,最終進(jìn)行搭積木式的組合調(diào)用。本文結(jié)合業(yè)務(wù)系統(tǒng)的部署情況,對部署進(jìn)行了優(yōu)化改進(jìn),以實現(xiàn)變更上線過程不中斷業(yè)務(wù)的功能[5]。經(jīng)過實測,該方案能極大提高上線的效率和準(zhǔn)確度。