李長(zhǎng)亮, 湯志福
(中遠(yuǎn)海運(yùn)科技股份有限公司,上海 200135)
隨著2020年1月1日全國(guó)高速公路取消省界收費(fèi)站,司乘用戶和高速公路從業(yè)人員對(duì)現(xiàn)有收費(fèi)系統(tǒng)數(shù)據(jù)傳輸?shù)募皶r(shí)性和準(zhǔn)確性有了更高的要求,各地區(qū)收費(fèi)業(yè)務(wù)相關(guān)系統(tǒng)應(yīng)用程序的升級(jí)頻率逐步加快。以寧夏回族自治區(qū)高速公路收費(fèi)站為例,其站級(jí)應(yīng)用程序在2020年5月上旬平均每天升級(jí)1次,全區(qū)共有81個(gè)收費(fèi)站,每次升級(jí)都需要3個(gè)運(yùn)維人員花費(fèi)1 h時(shí)間才能完成,不僅運(yùn)維效率低、運(yùn)維成本高,而且較易出錯(cuò)。目前軟件行業(yè)內(nèi)的應(yīng)用程序遠(yuǎn)程自動(dòng)部署技術(shù)已較為成熟,在很多互聯(lián)網(wǎng)公司都得到了實(shí)踐應(yīng)用,取得了很多成果。例如,以容器技術(shù)為核心的容器(即服務(wù)平臺(tái))在各保險(xiǎn)、證券和股份制銀行信用卡中心等金融機(jī)構(gòu)中的微信銀行等關(guān)鍵系統(tǒng)中得到了成功應(yīng)用,滿足高并發(fā)場(chǎng)景的業(yè)務(wù)需求,取得了較好的應(yīng)用效果。
本文主要研究高速公路收費(fèi)系統(tǒng)基于CentOS的應(yīng)用程序遠(yuǎn)程自動(dòng)部署及其實(shí)踐應(yīng)用,為后續(xù)的應(yīng)用程序自動(dòng)化運(yùn)維和自動(dòng)化監(jiān)控提供參考。
1)Tomcat:Tomcat 服務(wù)器是一個(gè)開(kāi)源的Web 應(yīng)用服務(wù)器,屬于輕量級(jí)應(yīng)用服務(wù)器,普遍應(yīng)用于中小型系統(tǒng)中和并發(fā)訪問(wèn)用戶不是很多的場(chǎng)合。
2)Jenkins:Jenkins是一個(gè)開(kāi)源的可擴(kuò)展的持續(xù)集成、交付和部署(軟件/代碼的編譯、打包、部署)的基于Web界面的平臺(tái)。對(duì)于允許持續(xù)集成和持續(xù)交付的項(xiàng)目而言,無(wú)論采用何種平臺(tái),都能處理任意類(lèi)型程序的構(gòu)建或持續(xù)集成。
3)SSH(Secure Shell):SSH是由IETF的網(wǎng)絡(luò)小組制定的建立在應(yīng)用層基礎(chǔ)上的安全協(xié)議。SSH較為可靠,專(zhuān)門(mén)用來(lái)為遠(yuǎn)程登錄會(huì)話和其他網(wǎng)絡(luò)服務(wù)提供安全性協(xié)議。利用 SSH 協(xié)議可有效防止在遠(yuǎn)程管理過(guò)程中發(fā)生信息泄露問(wèn)題。SSH最初是UNIX系統(tǒng)上的一個(gè)程序,后來(lái)迅速擴(kuò)展到了其他操作平臺(tái)中。SSH在正確使用時(shí)可彌補(bǔ)網(wǎng)絡(luò)中的漏洞。SSH客戶端適用于多種平臺(tái),幾乎所有的UNIX平臺(tái)(包括CentOS)都可運(yùn)行SSH。
4)Docker:Docker 是一個(gè)開(kāi)源的應(yīng)用容器引擎,既能讓開(kāi)發(fā)者打包其應(yīng)用和依賴包到一個(gè)可移植的容器中,并發(fā)布到所有流行的 Linux 機(jī)器上,又可實(shí)現(xiàn)虛擬化。容器完全采用沙箱機(jī)制,相互之間沒(méi)有任何接口,性能開(kāi)銷(xiāo)極低。
5)Docker鏡像(Images):Docker 鏡像可看作是一個(gè)特殊的文件系統(tǒng),除了提供容器運(yùn)行時(shí)所需的程序、庫(kù)、資源和配置等文件以外,還包含一些為運(yùn)行準(zhǔn)備的配置參數(shù)(如匿名卷、環(huán)境變量和用戶等)。鏡像不包含任何動(dòng)態(tài)數(shù)據(jù),其內(nèi)容在構(gòu)建之后也不會(huì)被改變。鏡像是 Docker 運(yùn)行容器的前提。
6)Docker容器(Container):Docker容器類(lèi)似于一個(gè)文件夾,包含某個(gè)應(yīng)用程序運(yùn)行所需的所有內(nèi)容,可對(duì)容器進(jìn)行啟動(dòng)、停止、遷移和刪除等操作。每個(gè)Docker容器都是獨(dú)立、隔離和安全的應(yīng)用平臺(tái)。Docker容器通過(guò)鏡像創(chuàng)建,換言之,容器是鏡像運(yùn)行起來(lái)的一個(gè)實(shí)例。
7)Docker倉(cāng)庫(kù)(Registry):Docker倉(cāng)庫(kù)是用來(lái)集中存放Docker鏡像的模塊。
對(duì)于應(yīng)用程序遠(yuǎn)程自動(dòng)部署而言,需解決的核心問(wèn)題有2個(gè),分別是遠(yuǎn)程操作和自動(dòng)部署。
1)遠(yuǎn)程操作是指遠(yuǎn)程操作機(jī)器內(nèi)的應(yīng)用程序:
(1)若應(yīng)用程序是Java語(yǔ)言開(kāi)發(fā)的,則可在機(jī)器內(nèi)采用Tomcat應(yīng)用服務(wù)器部署該應(yīng)用程序。Tomcat提供遠(yuǎn)程管理功能,可對(duì)部署在該應(yīng)用服務(wù)器內(nèi)的應(yīng)用程序進(jìn)行遠(yuǎn)程部署、卸載、停止和啟動(dòng)等操作。因此,可借助Tomcat的遠(yuǎn)程管理功能實(shí)現(xiàn)遠(yuǎn)程操作機(jī)器內(nèi)的Java應(yīng)用程序。
(2)若應(yīng)用程序不是Java語(yǔ)言開(kāi)發(fā)的,可借助CentOS系統(tǒng)內(nèi)的SSH協(xié)議實(shí)現(xiàn)遠(yuǎn)程操作機(jī)器內(nèi)的應(yīng)用程序。
2)自動(dòng)部署是指在不人為干預(yù)的情況下完成對(duì)應(yīng)用程序的部署。這些部署工作可手動(dòng)完成,但很耗時(shí)。采用自動(dòng)部署的方式既能顯著提高生產(chǎn)力,又能改進(jìn)軟件的整體質(zhì)量。在整個(gè)生命周期內(nèi)(包括部署在內(nèi))都使用好的工具,既能將人的干預(yù)最小化,又能節(jié)省時(shí)間。一旦去除人的干預(yù),軟件的質(zhì)量就會(huì)變得更加容易預(yù)測(cè)。開(kāi)源的Jenkins成功實(shí)現(xiàn)了自動(dòng)部署功能,已在很多領(lǐng)域得到應(yīng)用,取得了很好的效果。本文即采用Jenkins實(shí)現(xiàn)應(yīng)用程序遠(yuǎn)程自動(dòng)部署。
應(yīng)用程序遠(yuǎn)程自動(dòng)部署系統(tǒng)架構(gòu)見(jiàn)圖1,主要由自動(dòng)部署模塊和應(yīng)用程序2部分組成,其中自動(dòng)部署模塊包含單任務(wù)遠(yuǎn)程自動(dòng)部署組件、任務(wù)執(zhí)行監(jiān)測(cè)組件、批量任務(wù)執(zhí)行組件和持續(xù)集成組件等。
圖1 應(yīng)用程序遠(yuǎn)程自動(dòng)部署系統(tǒng)架構(gòu)
1)單任務(wù)遠(yuǎn)程自動(dòng)部署組件:提供在單個(gè)遠(yuǎn)程服務(wù)器上自動(dòng)部署應(yīng)用程序的功能。
2)任務(wù)執(zhí)行監(jiān)測(cè)組件:能自動(dòng)、實(shí)時(shí)監(jiān)測(cè)單個(gè)任務(wù)的執(zhí)行過(guò)程和結(jié)果,使運(yùn)維人員能及時(shí)跟蹤處理,并為后續(xù)的自動(dòng)運(yùn)維和自動(dòng)監(jiān)控提供技術(shù)支撐。
3)批量任務(wù)執(zhí)行組件:可同時(shí)觸發(fā)大批量任務(wù),并依次執(zhí)行各任務(wù)。
4)持續(xù)集成組件:當(dāng)應(yīng)用程序有新版本時(shí),新版本可持續(xù)集成和自動(dòng)部署。
控制流程見(jiàn)圖2,相關(guān)說(shuō)明如下:
圖2 控制流程
1)省中心服務(wù)器集群包括自動(dòng)部署服務(wù)器和Docker倉(cāng)庫(kù)服務(wù)器。自動(dòng)部署服務(wù)器安裝Jenkins和相關(guān)插件,同時(shí)包含Docker,以方便生成新的Docker鏡像;Docker倉(cāng)庫(kù)服務(wù)器主要用來(lái)存儲(chǔ)所有的Docker鏡像。
2)省中心服務(wù)器集群和收費(fèi)站站級(jí)服務(wù)器均在同一個(gè)網(wǎng)絡(luò)內(nèi),方便進(jìn)行通信交互。
3)自動(dòng)部署服務(wù)器發(fā)起遠(yuǎn)程自動(dòng)部署任務(wù)指令,根據(jù)每個(gè)任務(wù)指令的實(shí)際配置情況下發(fā)Java應(yīng)用程序的執(zhí)行文件。Docker鏡像從Docker倉(cāng)庫(kù)服務(wù)器上拉取。
當(dāng)采用Java語(yǔ)言開(kāi)發(fā)應(yīng)用程序時(shí),必須在生產(chǎn)環(huán)境中將該程序部署到Web應(yīng)用服務(wù)器中。目前Tomcat是應(yīng)用較廣泛的Web應(yīng)用服務(wù)器,該方案主要依賴Tomcat的遠(yuǎn)程管理功能。同時(shí),利用Jenkins實(shí)現(xiàn)單任務(wù)遠(yuǎn)程部署和持續(xù)集成功能。
Tomcat的遠(yuǎn)程管理功能默認(rèn)是關(guān)閉的,開(kāi)啟時(shí)需在Tomcat內(nèi)新增部署用戶和添加名為“manager-script”的角色,同時(shí)允許該用戶擁有該角色和遠(yuǎn)程訪問(wèn)Manager站點(diǎn)。配置完成之后重啟Tomcat即可。
單個(gè)任務(wù)的構(gòu)建流程見(jiàn)圖3(采用Jenkins的“Deploy to container Plugin”插件)。
圖3 單個(gè)任務(wù)的構(gòu)建流程
單個(gè)任務(wù)構(gòu)建之后的操作界面見(jiàn)圖4,其中:WAR/EAR files是待部署應(yīng)用程序執(zhí)行文件的名字;Credentials是第一步配置的遠(yuǎn)程服務(wù)中Tomcat遠(yuǎn)程管理的賬戶和密碼。
圖4 單個(gè)任務(wù)構(gòu)建之后的操作界面
Jenkins中的任務(wù)可人工單個(gè)觸發(fā),當(dāng)任務(wù)很多時(shí),若能批量觸發(fā)任務(wù),則能極大地降低錯(cuò)誤發(fā)生的概率,并提高工作效率。
批量執(zhí)行Jenkins中的任務(wù):獲取當(dāng)前Jenkins登錄用戶的Token,在每個(gè)任務(wù)配置頁(yè)面的“構(gòu)建觸發(fā)器”模塊勾選“觸發(fā)遠(yuǎn)程構(gòu)建”,在身份驗(yàn)證令牌中輸入該用戶的Token。這樣就可在Jenkins服務(wù)器內(nèi)執(zhí)行指定格式的Url指令,觸發(fā)單個(gè)任務(wù)的執(zhí)行。換言之,批量執(zhí)行這些Url指令即可批量觸發(fā)對(duì)應(yīng)任務(wù)的執(zhí)行。
利用Tomcat的遠(yuǎn)程管理功能遠(yuǎn)程部署應(yīng)用程序有很大的局限性,主要體現(xiàn)在只能處理部署在該Tomcat應(yīng)用服務(wù)器內(nèi)的應(yīng)用程序,對(duì)于采用其他語(yǔ)言開(kāi)發(fā)的應(yīng)用程序,需采用其他更通用的方式。
可將應(yīng)用程序及其依賴包打包到一個(gè)Docker容器內(nèi),通過(guò)部署該Docker鏡像達(dá)到部署應(yīng)用程序的目的。同時(shí),采用Jenkins提供單個(gè)任務(wù)的遠(yuǎn)程部署功能和新版本的持續(xù)集成功能。
應(yīng)用程序開(kāi)發(fā)測(cè)試完成之后,可直接采用Docker命令生成Docker鏡像。同時(shí),可將相關(guān)命令封裝在批處理腳本內(nèi),自動(dòng)生成Docker鏡像(在編譯生成Docker鏡像之前,需先編寫(xiě)Dockerfile,再調(diào)用Docker build命令生成鏡像)。
鏡像生成之后,需將鏡像推送到私有倉(cāng)庫(kù)內(nèi),以方便遠(yuǎn)程機(jī)器按需下載使用。Harbor是構(gòu)建企業(yè)級(jí)私有Docker鏡像倉(cāng)庫(kù)的開(kāi)源解決方案,提供友好的Web UI界面、角色和用戶權(quán)限管理及用戶操作審計(jì)等功能。Harbor支持離線安裝,通過(guò)離線安裝包即可完成安裝。配置好可訪問(wèn)的IP地址,啟動(dòng)Harbor之后即可對(duì)外提供服務(wù)。
采用Docker tag命令重命名鏡像(增加版本號(hào)信息以區(qū)分版本);采用Docker push命令將鏡像通過(guò)網(wǎng)絡(luò)推送至Harbor倉(cāng)庫(kù)內(nèi)。
在構(gòu)建新任務(wù)時(shí),首先配置遠(yuǎn)程服務(wù)器的SSH site,然后在“構(gòu)建”內(nèi)選擇“增加構(gòu)建步驟”,選擇“Execute Shell Script on remote host using SSH”編寫(xiě)要執(zhí)行的Shell腳本,具體Shell腳本執(zhí)行流程見(jiàn)圖5。
圖5 Shell腳本執(zhí)行流程
批量執(zhí)行Jenkins內(nèi)的任務(wù):首先,獲取當(dāng)前Jenkins登錄用戶的Token,在每個(gè)任務(wù)配置頁(yè)面觸發(fā)遠(yuǎn)程構(gòu)建模塊,設(shè)置該用戶的Token;隨后,在Jenkins服務(wù)器內(nèi)批量執(zhí)行指定格式的Url指令,觸發(fā)批量任務(wù)的執(zhí)行(該處理方式與第2.3節(jié)中的處理方式一致)。
基于CentOS的Java程序自動(dòng)部署方案已在寧夏路網(wǎng)與監(jiān)測(cè)應(yīng)急處置中心(以下簡(jiǎn)稱(chēng)“寧夏路網(wǎng)中心”)部署實(shí)施,該方案負(fù)責(zé)更新寧夏全省高速公路收費(fèi)站的站級(jí)程序,包含部站客戶端和部站服務(wù)端。部署方案任務(wù)截圖見(jiàn)圖6。
圖6 寧夏路網(wǎng)中心基于CentOS的Java程序自動(dòng)部署方案任務(wù)截圖
寧夏路網(wǎng)中心采用一臺(tái)CentOS服務(wù)器作為自動(dòng)部署服務(wù)器,當(dāng)每次Java應(yīng)用程序測(cè)試完成且可部署時(shí),運(yùn)維人員將程序可執(zhí)行文件(WAR包)拷貝至該服務(wù)器的固定目錄內(nèi),執(zhí)行分發(fā)腳本,分發(fā)WAR包到84個(gè)任務(wù)目錄內(nèi)。
實(shí)施該方案之前,全省84個(gè)收費(fèi)站單個(gè)應(yīng)用程序的更新部署任務(wù)需要3個(gè)運(yùn)維人員花費(fèi)1 h時(shí)間才能完成。實(shí)施該方案之后,此項(xiàng)任務(wù)僅需1個(gè)運(yùn)維人員花費(fèi)0.5 h時(shí)間就可完成,且只需盯著任務(wù)執(zhí)行結(jié)果即可(若任務(wù)執(zhí)行失敗,再執(zhí)行一次即可),部署效率提高了6倍。若同時(shí)更新部站客戶端和部站服務(wù)端,實(shí)施該方案之前合計(jì)需要6 h,實(shí)施該方案之后合計(jì)僅需0.75 h(Jenkins可并行執(zhí)行多項(xiàng)任務(wù),但因自動(dòng)部署服務(wù)器性能的原因,同時(shí)執(zhí)行的任務(wù)數(shù)量有限制),部署效率提高了8倍,極大地提高了運(yùn)維效率,降低了運(yùn)維成本和出錯(cuò)的概率。
本文主要對(duì)高速公路行業(yè)內(nèi)的應(yīng)用程序遠(yuǎn)程自動(dòng)部署方案進(jìn)行了研究,以期達(dá)到降本增效、有效促進(jìn)和提升高速公路行業(yè)設(shè)備運(yùn)維水平的目的。實(shí)踐結(jié)果表明,該方案適用于高速公路領(lǐng)域需遠(yuǎn)程部署應(yīng)用程序的場(chǎng)景和系統(tǒng)中。
在應(yīng)用程序部署完成之后,還需對(duì)應(yīng)用程序進(jìn)行自動(dòng)監(jiān)控、自動(dòng)維護(hù)等管理,這是未來(lái)重點(diǎn)研究和實(shí)踐的方向。
上海船舶運(yùn)輸科學(xué)研究所學(xué)報(bào)2021年1期