Docker容器及Spring Boot微服務應用java
1 什麼是Dockerlinux
傳統項目實施過程當中常常會出現「程序在我這跑得好好的,在你那怎麼就不行呢?! 」nginx
這是一個典型的應用場景,Docker image中包含了程序須要的全部的運行時依賴,好比java的程序,確定要在image中包含jdk;好比Python的程序,確定要在image中包含對應版本的Python解釋器。Docker把整個運行時環境打包放到image中,因此搞定了環境依賴問題!docker
Docker解決了運行環境和配置問題,方便發佈,也就方便作持續集成。數據庫
Linux自己就是個多租戶的操做系統,能夠多人共用,可是若是某個程序狂吃內存和CPU,佔用了太多系統資源,這就會影響其餘程序的運行。編程
因此虛擬機出現了,作了良好的資源隔離,不一樣用戶之間不會相互影響。可是,虛擬機有缺點:建立速度慢,遷移起來麻煩,由於中間加了一層guest os,有了性能損耗,很牛的物理機也就建立幾十個虛擬機,太浪費了……windows
相對虛擬機的重量級虛擬化方案, Docker出現了,讓虛擬化變得輕量了起來,建立一個container瞬間完成,秒級! 瀏覽器
Docker是更輕量的虛擬化,節省了虛擬機的性能損耗。安全
Docker 項目的目標是實現輕量級的操做系統虛擬化解決方案。Docker 的基礎是 Linux 容器(LXC-Linux Container)等技術。服務器
在 LXC 的基礎上 Docker 進行了進一步的封裝,讓用戶不須要去關心容器的管理,使得操做更爲簡便。用戶操做 Docker 的容器就像操做一個快速輕量級的虛擬機同樣簡單。
下面的圖片比較了 Docker 和傳統虛擬化方式的不一樣之處,可見容器是在操做系統層面上實現虛擬化,直接複用本地主機的操做系統,而傳統方式則是在硬件層面實現。
(每一個虛擬機都將擁有本身的操做系統以及應用程序必須的運行時環境)
(多個容器公用宿主機操做系統,每一個容器擁有獨立的應用程序運行時環境)
Docker 容器的啓動能夠在秒級實現,這相比傳統的虛擬機方式要快得多。 其次,Docker 對系統資源的利用率很高,一臺主機上能夠同時運行數千個 Docker 容器。
容器除了運行其中應用外,基本不消耗額外的系統資源,使得應用的性能很高,同時系統的開銷儘可能小。傳統虛擬機方式運行 10 個不一樣的應用就要起 10 個虛擬機,而Docker 只須要啓動 10 個隔離的應用便可。
具體說來,Docker 在以下幾個方面具備較大的優點。
對開發和運維(devop)人員來講,最但願的就是一次建立或配置,能夠在任意地方正常運行。
開發者可使用一個標準的鏡像來構建一套開發容器,開發完成以後,運維人員能夠直接使用這個容器來部署代碼。 Docker 容器很輕很快!容器的啓動時間是秒級的,大量地節約開發、測試、部署的時間。
Docker 容器的運行不須要額外的 hypervisor(虛擬化管理程序)支持,它是內核級的虛擬化,所以能夠實現更高的性能和效率。
Docker 容器幾乎能夠在任意的平臺上運行,包括物理機、虛擬機、公有云、私有云、我的電腦、服務器等。 這種兼容性可讓用戶把一個應用程序從一個平臺直接遷移到另一個。
特性 |
容器(Docker) |
虛擬機(VM) |
啓動 |
秒級 |
分鐘級 |
硬盤使用 |
MB級 |
GB級 |
性能 |
接近原生 |
弱於 |
系統支持量 |
單機支持上千個容器 |
單機支持幾十個 |
Docker並非全能的,設計之初也不是KVM之類虛擬化手段的替代品,簡單總結幾點:
1-2,有windows base應用的是不能使用Docker的
3-5主要是看用戶的需求,究竟是須要一個container仍是一個VM, 同時也決定了docker做爲 IaaS 不太可行
6-7雖然是docker自己不支持的功能,可是能夠經過其餘手段解決(disk quota, mount --bind)。總之,選用container仍是vm, 就是在隔離性和資源複用性上作權衡
Type-1型是指在服務器的硬件平臺上先部署虛擬機管理層(Hypervisor),再在Hypervisor之上生成虛擬機,每一個虛擬機再安裝操做系統、運行庫與相關的應用.Type-1虛擬化比較常見的是VMware的vSphere、微軟的Hyper-V、Linux的KVM以及Xen.
Type-2型則在裸機之上先安裝操做系統(好比Linux或Windows),再安裝Hypervisor。Type-2的典型表明是VMware的Workstation以及Oracle的VirtualBOX。
因爲Type-1型Hypervisor更接近硬件底層,因此能夠下降更多的系統開銷,但就Hypervisor自己來講,仍然要有一層基本的OS「墊底」,這也是其仍然會有系統開銷的緣由。
而對於容器技術來講,因爲自己就源於操做系統的內核(Linux Kernel),因此也就基本不存在Hypervisor所帶來的開銷
與傳統的服務器虛擬化相比,Docker的一重要特色就是在實現應用間隔離的同時,沒有了對於傳統虛擬化來講是必須的Hypervisor虛擬化管理層,由於從本質上來說Docker的內核與Linux是一體的。Docker的根基——LXC就是一個將Linux運行時、庫以及其餘軟件運行支撐環境與相關應用進行封閉的技術。從Linux的內核來看,LXC就至關於系統的一個本地進程,實質上與一個裸機(無虛擬化)應用沒有什麼區別,從而無需額外的虛擬化指令以及相應的系統虛擬化開銷。由於在傳統的虛擬化平臺中,不管Hypervisor作得再輕薄,虛擬機都要先通過本地的OS再透過Hypervisor調用服務器的物理硬件資源,這與直接以系統進程出現的LXC相比,確定會形成額外的性能影響。
從Docker的應用封裝架構中,能夠看出其最基礎的運行內核與底層鏡像就源於Linux的內核,用戶能夠將利用Dockerfile生成好的應用鏡像,上傳至遠端的Docker Registry(好比Docker公司本身運營的雲服務,或是私建的Docker Registry),也能夠從Docker Registry裏下拉一個別人已經創建好的鏡像直接投入到容器中進行運行,相比之下Docker顯然帶給了LXC更靈活的部署與快速應變的能力
在Docker體系中,最關鍵的就是兩個——Docker Registry(經過Docker Hub進行索引)以及Docker Engine,前者在遠端(或稱雲端)負責收集與分發Docker的應用鏡像(Images),後者則在客戶端負責構建Docker應用容器,這明顯就是一個雲服務的AAS理念,固然用戶也能夠在本身的數據中心內部創建私有的Docker Registry,以方便在私有云內迅速生成本身的Docker集羣,以應對靈活的、大規模的應用擴展需求。此時,也至關於在企業數據中心內部造成了一個雲+端的Docker架構。
Docker在英語裏的意思爲「碼頭工人」,而其Logo就好似一艘酷似鯨魚的大船運送一堆集裝箱前往各地的碼頭。而從其理論上看,Docker就像是一個集裝箱,利用LXC技術來整合不一樣規模、類型、層級的應用鏡像,先經過集中彙總再有序的分發——每一個碼頭就是一臺服務器(或VM),大船就是Registry,碼頭的工人就是核心Engine,進行集裝箱的裝配,固然它還須要一系列的外圍的支持(好比最重要的管理)。但從整體的 場景來講,Docker的名字仍是很是貼切的。
Docker Image:
Docker image是一個只讀模板,用於建立Docker容器。Image中能夠包含linux操做系統、Apache或者Web應用程序等等,用戶能夠下載已經建立好的Docker image,也能夠建立Docker image給其餘用戶使用。每一個image是由不少層組成,Docker經過Union File Systems將這些層綁定在一個image中。每一個image都以一個初級image作爲基礎,而後經過操做指令在這些初級image上添加新層,操做指令能夠是運行的命令、添加文件或目錄或者建立可用操做環境等。這些操做指令都被保存在「Dockerfile」文件中。
Docker Container:
Docker image的運行實例。Docker Containers能夠運行、啓動、中止或者被刪除,每一個container都是隔離的安全應用平臺。
Docker registries:
Docker registries用於保存Docker image,也分公用和私用二種。公用的Docker registry就是Docker Hub,用戶也能夠建立私有的Docker registry,爲其餘用戶提供Docker images下載。
Dockerfiles:
Dockerfile是對Docker Container建立過程的描述腳本。每一個Dockerfile詳細說明了開始的基礎鏡像,以及隨後一系列在容器中運行的命令和添加到容器中的文件。Dockerfile也能夠說明容器對外的端口,啓動時的工做目錄和缺省執行的命令。
LXC:(Linux Container)
Linux Container容器是一種內核虛擬化技術,能夠提供輕量級的虛擬化,以便隔離進程和資源,並且不須要提供指令解釋機制以及全虛擬化的其餘複雜性。至關於C++中的NameSpace。容器有效地將由單個操做系統管理的資源劃分到孤立的組中,以更好地在孤立的組之間平衡有衝突的資源使用需求。
VM:(Virtual Machines)
指經過軟件模擬的具備完整硬件系統功能的、運行在一個徹底隔離環境中的完整計算機系統。
Host OS:
指物理存在的計算機上運行的操做系統。宿主機操做系統。
Guest OS:
指運行在VM上的操做系統。例如在一臺安裝了Windows NT的計算機上安裝了Vmware,那麼,HOST指的是安裝Windows NT的這臺計算機,其Host′s OS爲Windows NT。VM上運行的是Linux,那麼Linux即爲Guest OS。
Hypervisor:
Hypervisor是一種運行在物理服務器和操做系統之間的中間軟件層,可容許多個操做系統和應用共享一套基礎物理硬件,所以也能夠看做是虛擬環境中的「元」操做系統,它能夠協調訪問服務器上的全部物理設備和虛擬機,也叫虛擬機監視器。當服務器啓動並執行Hypervisor時,它會給每一臺虛擬機分配適量的內存、CPU、網絡和磁盤,並加載全部虛擬機的客戶操做系統。
目前市場主要廠商及產品:VMware vSphere、微軟Hyper-V、Citrix XenServer 、IBM PowerVM、Red Hat Enterprise Virtulization、Huawei FusionSphere、開源的KVM、Xen、VirtualBSD等。
Bootfs:(Boot File System)
主要包含 bootloader 和 kernel, bootloader主要是引導加載kernel, 當boot成功後 kernel 被加載到內存中後 bootfs就被卸載了.
Rootfx:(Root File System)
rootfs包含的就是典型 Linux 系統中的 /dev(外設訪問接口信息),/proc(系統設備信息),/bin(系統工具集), /etc(APP配置信息) 等標準目錄和文件。對於不一樣的linux發行版, bootfs基本是一致的, 但rootfs會有差異, 所以不一樣的發行版能夠公用bootfs。
微服務架構風格是一種使用一套小服務來開發單個應用的方式途徑,每一個服務運行在本身的進程中,經過輕量的通信機制聯繫,常常是基於HTTP資源API,這些服務基於業務能力構建,可以經過自動化部署方式獨立部署,這些服務本身有一些小型集中化管理,能夠是使用不一樣的編程語言編寫,正如不一樣的數據存儲技術同樣。
Docker的細粒度鬆耦合可以讓咱們用一個Docker容器裝載一個場景功能,也就是按照功能角色分類,每一個Docker裏面裝一個服務或應用,一個服務器上能夠運行多個Docker,或者多個Docker分散到多個服務器上運行。整個項目架構能夠按照業務邏輯的規劃以細粒度的方式分散在各個Docker容器中,並根據HTTP REST API的方式進行整合聯動。
(Docker爲基礎的微服務架構)
本圖由上到下分別由:Nginx負載均衡層,綜合業務服務層,單業務服務層,數據庫層等共同組成Docker爲基礎的微服務架構。圖中每一個服務節點均裝載入單獨的Docker Container中運行,並對外暴露基於Http協議的Port供外界訪問(數據庫容器仍然是基於JDBC的數據庫鏈接池方式對其訪問)。
此框架實現重點爲,在項目前期經過詳細的功能需求分析並按業務邏輯的耦合度劃分紅多個服務節點,依靠Docker的獨立且低耦合特性在物理層面上實現項目的細粒度分解。
其優勢是:
缺點爲,在項目設計前期,須要花費較多的時間進行詳細的業務邏輯劃分及系統分析。
接下來,咱們將實現該架構圖中的每一個Docker節點的關鍵技術。
Spring Boot充分利用了JavaConfig的配置模式以及「約定優於配置」的理念,可以極大的簡化基於Spring MVC的Web應用和REST服務開發。
Spring 4倡導微服務的架構,微服務架構倡導將功能拆分到離散的服務中,獨立地進行部署,Spring Boot可以很方便地將應用打包成獨立可運行的JAR包,所以在開發模式上很契合這一理念。
特色:
• 建立獨立Spring應用程序
• 嵌入式Tomcat,Jetty容器,無需部署WAR包
• 簡化Maven及Gradle配置
• 儘量的自動化配置Spring
• 直接植入產品環境下的實用功能,好比度量指標、健康檢查及擴展配置等
• 無需代碼生成及XML配置
在Eclipse中利用Maven的Spring boot+Docker模板搭建項目框架,實現步驟:
1.下載Eclipse的Maven插件。
2.在Eclipse中選擇SpringBoot-Docker模板。
3.建立SpringBoot-Docker項目
基於該模板建立SpringBoot項目後,目錄結構如上圖,編譯後會生成Dockerfile文件及<項目名>.jar文件。
4.在Docker環境下生成Docker Image鏡像文件
因爲已經有了Dockerfile文件及本項目的.jar文件,能夠將其拷貝到虛擬機Docker環境中,並運行例如:docker build -t <example-service> . 指令,將Dockerfile描述編譯成鏡像文件,並進入本地Docker registries倉庫中。
5.運行Docker Image文件,造成Container實例,與宿主機創建端口映射。
運行例如:docker run -p 48080:8080 -d <example-service> 指令,啓動該項目的Container實例。
6.在瀏覽器上訪問宿主機的48080端口,經過REST API訪問業務接口。
至此,基於Docker Container的Spring boot項目啓動完畢,並可在瀏覽器中訪問。
Nginx ("engine x") 是一個高性能的 HTTP 和 反向代理 服務器,也是一個 IMAP/POP3/SMTP 代理服務器。
在高鏈接併發的狀況下,Nginx可以支持高達 50,000 個併發鏈接數的響應。Nginx也可做爲負載均衡服務器,Nginx 既能夠在內部直接支持 Rails 和 PHP 程序對外進行服務,也能夠支持做爲 HTTP代理服務器對外進行服務。Nginx採用C進行編寫,不管是系統資源開銷仍是CPU使用效率都比 Perlbal 要好不少。
Nginx 是一個安裝很是的簡單,配置文件很是簡潔(還可以支持perl語法),Bugs很是少的服務器:Nginx 啓動特別容易,而且幾乎能夠作到7*24不間斷運行,即便運行數個月也不須要從新啓動。你還可以不間斷服務的狀況下進行軟件版本的升級。
1.先訪問hub.docker.com下載Nginx的Docker Image
可在虛機中的Docker環境中使用指令例如:docker pull nginx下載鏡像文件。
2.查看該鏡像文件
可以使用docker images指令查看下載後的nginx鏡像文件狀態。
3.創建nginx反向代理映射及動靜資源分離映射
4.啓動Nginx服務
可以使用以下指令例如:
docker run -d -p 8080:8080 -v /some-path/nginx.conf:/etc/nginx/nginx.conf:ro <nginx-container> 啓動nginx代理服務。
至此,基於Docker的Nginx與Spring Boot反向代理架構搭建完畢。
1.在Docker hub中下載Postgre Image鏡像文件
可使用tag指令有針對性下載指定版本的鏡像文件。例如:
docker pull postgres:9.4.4
2.運行Postgres Container實例
例如使用指令:
docker run -p 5432:5432 -e POSTGRES_PASSWORD=654321 -d <example-name>
3.確認Spring Boot項目中的數據庫鏈接配置是否正確
至此,微服務架構圖中全部層次節點均在Docker容器中部署完畢。
做者自述:
本人從事十六年WINDOWS應用/遊戲/設備/WEB開發,目前從事Linux,Docker及CAAS雲平臺架構設計及開發。
基於全球開源共享理念,本人會分享更多原創及譯文,讓更多的IT人從中受益,與你們一塊兒進步!
基因Cloud 原創,轉發請註明出處
1738387@qq.com (工做繁忙,有事發郵件,QQ不加,非要事勿擾,多謝!)
2015年6月2日