張瑞林 吳學敏


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