張瑞林 吳學(xué)敏
摘要:龐雜而版本升級頻繁的互聯(lián)網(wǎng)后端服務(wù)系統(tǒng),需要一種內(nèi)部耦合性低的方法來實現(xiàn)靈活開發(fā)、便捷部署。該文分析了Docker容器的特點及其核心技術(shù),然后通過實例來說明把一個復(fù)雜的后端服務(wù)拆分為多個微服務(wù)子系統(tǒng),在Docker官方公布的OpenJDK、MySql等基礎(chǔ)鏡像之上構(gòu)建新鏡像,并運行這些鏡像作為微服務(wù),以此來提供整體后端服務(wù)的基本方法,最后總結(jié)了本方法的優(yōu)缺點。
關(guān)鍵詞: Docker技術(shù);后端服務(wù);微服務(wù)
中圖分類號:TP3 ? ? ? ?文獻標(biāo)識碼:A
文章編號:1009-3044(2019)13-0281-02
隨著互聯(lián)網(wǎng)信息技術(shù)的發(fā)展,一些系統(tǒng)變得更加龐大復(fù)雜,后端系統(tǒng)給前端Web或應(yīng)用程序提供的服務(wù)越來越大,功能越來越多。因此,這些臃腫的后端系統(tǒng)帶來一系列問題:開發(fā)者難以掌握整個大系統(tǒng)全部細(xì)節(jié),修BUG或者增加新功能都不容易;無論修改多小的功能都要對整個系統(tǒng)進行更新,帶來潛在未知風(fēng)險;每次版本更新時,重新啟動也要耗費較長時間等等。為了解決上述問題,把復(fù)雜的后端系統(tǒng)分割為多個微小系統(tǒng)是一個不錯的選擇,因此本文提出了一種在后端服務(wù)中應(yīng)用Docker容器作為載體來提供微服務(wù)的解決方法。
1 Docker容器及其核心技術(shù)
Docker技術(shù)是dotCloud 公司在2013年發(fā)布的基于Go語言實現(xiàn)的云開源項目,與已有的傳統(tǒng)虛擬化技術(shù)相比,Docker技術(shù)有著獨特的優(yōu)勢,比如輕量級、自由度更大、啟動快等特點,并且Docker技術(shù)可以按照所需的服務(wù)和應(yīng)用打包起來建立執(zhí)行的環(huán)境。
Docker有3個核心概念,鏡像、容器以及倉庫。其中Docker鏡像是一個由一層層只讀層構(gòu)成的模板文件。Docker容器使用了Linux操作系統(tǒng)內(nèi)核的命名空間(Namespace)、控制組(Control Group)、聯(lián)合文件系統(tǒng)(Union File System)等三個關(guān)鍵技術(shù)。Docker容器使用Linux內(nèi)核的Namespace特性進行各個容器之間的隔離,通過內(nèi)核的Control Groups進行使用資源的限制和監(jiān)控,通過高性能分層文件系統(tǒng)Union File System使得鏡像可以通過分層實現(xiàn)和繼承。圖1是Docker容器技術(shù)的架構(gòu)圖。
1.1 命名空間Namespace技術(shù)
Namespace技術(shù)是容器的隔離性的基礎(chǔ),Namespace將容器的進程、網(wǎng)絡(luò)、消息、文件系統(tǒng)、UTS等系統(tǒng)資源和用戶空間隔離開。使用了Namespace之后,進程在Namespace之外展示為一個普通用戶,但是在Namespace內(nèi)則展現(xiàn)為root用戶(uid=0)。也就是進程在這個Namespace里擁有root權(quán)限,在Namespace外面只有普通用戶的權(quán)限。通過Namespace特性,每個Docker容器都有自己的獨立的命名空間,運行在該Docker中的應(yīng)用程序和運行中獨立的操作系統(tǒng)中類似,這種隔離性保證了容器之間彼此互不影響。
1.2 控制組Control Groups技術(shù)
Control Groups技術(shù)對進程起了限制資源的作用。這些資源包括CPU,內(nèi)存,存儲,網(wǎng)絡(luò)等。通過Control Groups還可以實時的監(jiān)控進程的監(jiān)控和統(tǒng)計信息。比如在啟動Docker容器時,可以指定允許使用的內(nèi)存大小,Docker 會自動為容器在目錄/sys/fs/cgroup/memory/Docker/<容器的完整長ID>中創(chuàng)建相應(yīng) Cgroup 配置文件。Control Groups技術(shù)為Docker容器限定使用資源提供了技術(shù)支持。
1.3 聯(lián)合文件系統(tǒng)Union File System技術(shù)
聯(lián)合文件系統(tǒng)Union File System是一種輕量級高性能的分層文件系統(tǒng),能把不同物理位置的目錄合并一起掛載到同一個虛擬目錄下。Docker容器使用了聯(lián)合文件系統(tǒng)技術(shù)實現(xiàn)了鏡像的分層。在該文件系統(tǒng)中,每次修改都可以看作創(chuàng)建了一個新的層Layer,Docker鏡像就是由一層或多層這樣的Layer所構(gòu)成。鏡像層都是只讀的,但是鏡像啟動成為容器,在容器層是可寫的。Docker鏡像之間有順序關(guān)系,最下面一層為基礎(chǔ)鏡像,其他層都會有一個指針指向下一層,上層鏡像依賴于下層鏡像。
2 使用Docker容器構(gòu)建后端微服務(wù)
2.1 后端服務(wù)整體架構(gòu)
下文以某公司的信息服務(wù)后端系統(tǒng)為例,介紹把該后端系統(tǒng)分割為多個微服務(wù)子系統(tǒng),再以Docker容器作為載體創(chuàng)建后端服務(wù)的方法。先按照業(yè)務(wù)邏輯進行劃分后端微服務(wù),分為生產(chǎn)部后端應(yīng)用服務(wù)、生產(chǎn)部數(shù)據(jù)庫服務(wù)、MQTT消息發(fā)送服務(wù)、售后后端應(yīng)用服務(wù)、售后數(shù)據(jù)庫服務(wù)等5個微服務(wù),這些微服務(wù)都以Docker容器的方式獨立運行于一個主機里,主機的操作系統(tǒng)是UBUNTU 16.04。圖2是以Docker為載體的后端服務(wù)系統(tǒng),Docker1~5分別承載了上面的五個微服務(wù),各個微服務(wù)的Docker以“IP:Port”的方式對外提供后端服務(wù),即要訪問某個服務(wù),需要知道該服務(wù)的IP和端口號。
2.2 Docker容器微服務(wù)組建步驟
該后臺系統(tǒng)分割為5個Docker微服務(wù)后,需要Docker1和Docker4提供JAVA環(huán)境來運行JAR包,需要Docker3提供MQTT代理服務(wù)器broker(作用是接受發(fā)布者發(fā)布的所有消息再按訂閱規(guī)則發(fā)給不同的消息訂閱者),需要Docker2和Docker5提供MySql數(shù)據(jù)庫服務(wù)。下面是這5個Docker容器微服務(wù)的組建步驟:
(1)去Docker官方倉庫去獲取這3種鏡像(JAVA運行環(huán)境、MQTT代理服務(wù)器、MySql數(shù)據(jù)庫環(huán)境)。具體地是,安裝好Docker后,使用“Docker pull openjdk”命令從倉庫里拉取openjdk這個Docker鏡像到本地,這鏡像提供了JAVA運行環(huán)境;使用“Docker pull toke/mosquitto”命令拉mosquitto鏡像(MQTT服務(wù)鏡像);使用“Docker pull mysql”命令拉取MySql鏡像。
(2)把生產(chǎn)部后端服務(wù)的JAVA JAR包放到JDK鏡像后生成新的鏡像。具體地是,新建Dockerfile,使用Docker build命令按照Dockerfile里設(shè)定的規(guī)則來創(chuàng)建Docker鏡像。在這個基礎(chǔ)鏡像之上,把生產(chǎn)部后端服務(wù)的JAVA JAR包拷貝到新鏡像里,再設(shè)定該容器啟動時自動運行該JAR包即可。
(3)使用Docker run命令運行第2步生成的鏡像來創(chuàng)建Docker容器,以此提供生產(chǎn)部后端微服務(wù),運行時需要指定容器端口和映射到宿主機的端口,因為最終是需要通過“IP:端口”的形式來提供后端服務(wù),每個Docker容器都會自動獲取一個內(nèi)網(wǎng)IP。
(4)把售后后端服務(wù)的JAVA JAR包放到JDK鏡像后生成新的鏡像。這一步的和第2步類似,使用的JAR包換成售后后端的JAR包即可。
(5)運行第4步生成的鏡像來創(chuàng)建Docker容器,以此提供售后后端微服務(wù),這一步和第3步類似,注意,指定的宿主機映射端口號要不同。
(6)運行第1步獲得的MySql鏡像創(chuàng)建生產(chǎn)部數(shù)據(jù)庫容器。運行時也指定容器端口和映射到宿主機的端口。采用數(shù)據(jù)卷(Volume)的方式把MySql容器內(nèi)部的數(shù)據(jù)庫目錄/var/lib/mysql掛載到宿主機的目錄(比如新建一個目錄/host/mysql_data/)下,這樣,容器內(nèi)的MySql數(shù)據(jù)文件就會持久化保存到宿主機,即使容器本身被刪除,我們也可以在宿主機上的掛載目錄里找到數(shù)據(jù)庫文件。
(7)運行第1步獲得的MQTT鏡像來提供MQTT代理服務(wù)器。運行時要指定映射到宿主機的端口和MQTT的端口。
3 Docker容器作為后端服務(wù)載體的優(yōu)缺點分析
在采用Docker容器作為后端微服務(wù)的載體后,主要有下列優(yōu)點:
(1)Docker容器可以打包了整個運行環(huán)境,確保了開發(fā)環(huán)境、測試環(huán)境以及生產(chǎn)環(huán)境的一致性。這樣就不會出現(xiàn)開發(fā)環(huán)境運行良好,到生產(chǎn)環(huán)境就發(fā)生異常等問題。生產(chǎn)環(huán)境出現(xiàn)問題,也可以方便地把生產(chǎn)環(huán)境的鏡像拿到開發(fā)環(huán)境進行問題重現(xiàn)和調(diào)查。
(2)Docker鏡像占用硬盤空間比傳統(tǒng)虛擬機小,傳統(tǒng)虛擬機鏡像通常以G字節(jié)為單位,Docker鏡像通常只有幾M到幾百M字節(jié)。尺寸的減小不僅僅降低了硬盤資源占用,在傳輸文件時也更加快捷。
(3)Docker容器在對硬件要求較傳統(tǒng)虛擬機低,因為Docker容器之間共用了宿主機的操作系統(tǒng)資源。一臺主機上可以運行幾十、幾百甚至更多的Docker容器。
Docker容器作為后端微服務(wù)的載體也存在一些不足之處,主要有下面幾點:
(1)Docker容器之間跟宿主機共用一些系統(tǒng)資源,隔離性不徹底,會存在安全上的未知風(fēng)險。
(2)Docker基于64位Linux內(nèi)核特性,所以在其他操作系統(tǒng)比如windows或MAC上不能直接使用Docker。
(3)在Docker里的程序調(diào)用系統(tǒng)服務(wù)時會有一些不便,比如,使用系統(tǒng)定時任務(wù)crontab,用法和普通的主機里的crontab不一樣。
4 結(jié)語
Docker官方提供了很多流行應(yīng)用的鏡像文件,比如本文用到OpenJDK、MySql、MQTT等鏡像,我們可以在這些基礎(chǔ)鏡像之上創(chuàng)建自己的應(yīng)用鏡像。采用這些鏡像為載體,把復(fù)雜的后端系統(tǒng)劃分為多個小系統(tǒng),可以充分利用Docker隔離性、系統(tǒng)資源要求相對低、部署方便等特性,特別適合模塊多,版本更新頻繁的后端系統(tǒng),在實際工程應(yīng)用中已經(jīng)取得了良好效果。
參考文獻:
[1] Sam Newman.微服務(wù)設(shè)計[M].北京:人民郵電出版社,2016:23-26.
[2] 楊保華.Docker技術(shù)入門與實踐[M].北京:機械工業(yè)出版社2016:165-171.
[3] 謝睿.Docker技術(shù)在Web服務(wù)中的應(yīng)用[J].電子技術(shù)與軟件工程,2018(16):173.
【通聯(lián)編輯:代影】