1. 程式人生 > >Docker部署Spring cloud微服務詳細講解 (一)

Docker部署Spring cloud微服務詳細講解 (一)

一、為什麼要使用Docker部署Spring Cloud專案

        說目前最流行的java開發方式就是Spring Boot和Spring Cloud應該不為過。Spring Boot進一步加強了“約定大於配置”這一Spring的中心思想,使得我們開發人員能夠更快捷,更便利的開發Spring專案,也使得開發java web變得不再那麼費勁。而Spring Cloud的出現更是讓我們專案的開發有了更多的選擇,Spring Cloud整合並封裝netfix中的ribbon,eureka,hystrix,feign和zull等十分出色的專案,為我們提供了服務註冊與發現,客戶端的負載均衡和路由分發等功能,為現在的大部分中小企業開發分散式架構提供了一整套的解決方案,大大提高了工作效率,個人認為Spring Cloud在未來一定會像Spring一樣的出色。而Docker的出現讓容器化技術得以普及,更快的部署和維護與Spring Cloud的結合,能讓我們不再像以前一樣為了某一個模組的增加而伺服器上大動干戈,還需要考慮環境的問題,現在只需要一句docker start .....便可輕鬆實現服務的擴充套件。

二、如何使用Docker來部署Spring Cloud專案

       Spring Cloud專案必須基於Spring Boot專案來開發,所以這裡講解Spring Boot專案的部署,Spring Cloud專案也是同理。博主使用的是Dockerfile的形式來部署。廢話不多說,先張貼程式碼:

FROM frolvlad/alpine-oraclejdk8
VOLUME /usr/test
ADD test.jar app.jar
EXPOSE 8001
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]
FROM:

Docker是基於映象的部署,幸運的是Docker官方和開發者們為我們維護了許多高質量的Docker映象,而基於這些映象我們能做出符合自己需求的映象。此處的FROM意思為我們即將要建立的映象的基礎映象的名字,這個名字可以是我們本地已有的映象,也可以是Docker Hub上的映象,如果是Docker Hub上的映象,此時docker daemon會為我們自動下載該映象。還有一個要注意的點,如果是本地映象要加上版本(映象名:版本號),否則預設版本號為latest。

VOLUME:

    Docker的執行相當於是作業系統的一個程序,但是該程序又與普通程序有些許不同,因為該程序內部維護著的是我們的一個微服務的完整結構,而往往專案中需要執行的微服務都有記錄日誌或者其他寫出檔案的功能。設想一下這樣的情況:我們的微服務現在正在執行,但是訪問量突然增大,開發人員又沒有關注到這一點,沒有進行水平擴充套件,這時候很有可能這個微服務就down了,而這個微服務一旦down了之後,出現的情況就是整個容器的status就變成了Exited,而此時如果將容器刪除,容器中的所有資料卷會跟隨容器一起刪除,因為這些資料卷是臨時的。此處的對映路徑為/usr/test

。這是我們自定義的對映路徑,後續要演示記錄日誌的功能。當然也可以指定/tmp 其效果都是在主機的/var/lib/docker/volumes目錄下建立一個臨時檔案,並連結到容器的連結路徑。而為什麼連結到容器的/tmp目錄呢?因為 Spring Boot 使用的內嵌 Tomcat 容器預設使用/tmp作為工作目錄。當然此處的/tmp也可以變成你的日誌記錄資料夾,這樣就可以在本地實時檢視日誌記錄了。

ADD:

將我們自身的專案admin.jar作為app.jar加入到容器中。

EXPORT:

    該命令用於宣告在執行時容器提供服務的埠。注意:這只是一個宣告,執行時並不會因為該宣告就開啟相應的埠。該指令的作用是幫助映象使用者理解該映象服務的守護埠;其次是當執行時使用隨機對映時(即run命令的-P引數),會自動對映EXPORT的埠。

ENTRYPOINT:

    該命令制定Docker容器啟動時執行的命令,可多次設定,但只有最後一條會生效。

    ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]這條命令中可能部分讀者會對   -Djava.security.egd=file:/dev/./urandom   這條命令有疑惑,這是因為linux中和windows中取隨機數時的參考策略不同,linux預設的隨機數會被取完,導致返回-1.而制定/dev/./urandom這個取隨機數的策略時,當隨機數取完之後會返回偽隨機數,不至於影響業務。

三、建立映象並執行

我們jar包中只有一個test類

package com.example.test.rest;
import java.io.File;
import java.io.FileOutputStream;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class TestRest {
	@RequestMapping("/test/{info}")
	public String test(@PathVariable(value="info") String info) throws Exception {
		FileOutputStream fos = new FileOutputStream(new File("/usr/test/test.txt"));
		fos.write(info.getBytes());
		fos.close();
		return "test ok";
	}
}

  當我們訪問/test/{info}時便將info的資訊輸出到/usr/test/test.txt中。廢話不多說開始打包。


檔案上傳到裝有Docker的伺服器上。

執行命令   docker build -t test/test8001:test .

-t 表示打包成功後的映象tag   不要忘了最後一個點。.表示Dockerfile檔案和jar包在同一個路徑,如果不在需要寫出Dockerfile的絕對路徑。


打包成功!!!

我們先關閉所有正在執行的docker容器,並刪除/var/lib/docker/volumes中的所有檔案,呈現如下狀態


執行我們的docker 映象。


此時會返回一長串字元:06764ea7337484494183557c7425e706dd31e2333aced6034b7a53354c6c8a75

這串字元就是我們容器的唯一ID。

現在我們再來看看資料夾     /var/lib/docker/volumes


我們可以看到這裡產生了一個資料夾。但是這裡的資料夾名稱卻和我們的容器ID不同,接著我們再看看/var/lib/docker/containers這個目錄下有什麼東西。


在containers目錄下出現了容器的唯一ID。這裡面儲存的是我們容器執行需要的資料。那麼我們怎麼看到volumes下的目錄呢?

我們可以據下圖的方式檢視:


根據docker inspect 容器ID   這條命令可以檢視到容器的詳細資訊。但是顯示的資料太多了,我們也可以選擇性的檢視。

根據 docker inspect --format "{{.Mounts}}" 06764ea73374

--format  根據模板來檢視資訊,我們這裡就檢視Mounts的資訊


對應著docker inspect 06764ea73374 中劃紅線的這一段

從上面我們可以看到。我們已經成功將容器中的/usr/test目錄掛載到了主機的/var/lib/docker/volumes/5beee516b4656b67f907cf7178c0323434a4c7b2d044b4059f9e9b52c58e054a/_data目錄下。上圖劃紅線中的name後的字串也就是我們在/var/lib/docker/volumes下面看到的資料夾名稱。

接著我們嘗試訪問:


上圖顯示訪問成功了。那麼在/var/lib/docker/volumes/5beee516b4656b67f907cf7178c0323434a4c7b2d044b4059f9e9b52c58e054a/_data這裡面應該會有我們需要的test.txt檔案。


我們可以看到。果然出現了!!!!那麼會有hello world!字樣嗎?我們可以開啟來看看。


果然出現了!!!這就證明我們的檔案掛載成功了。

這時就算你停止容器,該檔案也不會消失。基於此我們可以輕鬆的搭建微服務的日誌系統。

下節講解docker部署微服務時網路連線的注意點。

以上內容均為本人愚見,望各位大牛在評論中多加指點。小弟感激不盡!!!