您好,登錄后才能下訂單哦!
本篇內(nèi)容介紹了“Java SpringBoot項目怎么構(gòu)建Docker鏡像調(diào)優(yōu)”的有關(guān)知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細(xì)閱讀,能夠?qū)W有所成!
前言:
以前的 SpringCloud 微服務(wù)時代以 “Jar包" 為服務(wù)的基礎(chǔ),每個服務(wù)都打成 Jar 供服務(wù)間相互關(guān)聯(lián)與調(diào)用。而 現(xiàn)在隨著 Kubernetes 流行,已經(jīng)變遷到一個鏡像一個服務(wù),依靠 Kubernetes 對鏡像的統(tǒng)一編排進(jìn)行對服務(wù)進(jìn)行統(tǒng)一管理。在對 Kubernetes 微服務(wù)實踐過程中,接觸最多的肯定莫過于 Docker 鏡像。由于本人使用的編程語言是 Java,所以對 Java SpringBoot 項目接觸比較多,所以比較關(guān)心如何更好的通過 Dockerfile 編譯 Docker 的鏡像。
Kubernetes 微服務(wù)簡單說就是一群鏡像間的排列組合與相互間調(diào)的關(guān)系,故而如何編譯鏡像會使服務(wù)性能更優(yōu),使鏡像構(gòu)建、推送、拉取速度更快,使其占用網(wǎng)絡(luò)資源更少這里優(yōu)化,更易使用成為了一個重中之重的事情,也是一個非常值得琢磨的問題。這里我將對 SpringBoot 項目打包 Docker 鏡像如何寫 Dockerfile 的探究進(jìn)行簡單敘述。
系統(tǒng)環(huán)境:
Docker 版本: 18.09.3
Open JDK 基礎(chǔ)鏡像版本:openjdk:8u212-b04-jre-slim
測試用的鏡像倉庫:阿里云 Docker Hub
項目 Github: https://github.com/my-dlq/blog-example/tree/master/springboot-dockerfile
這里將用常規(guī) SpringBoot 編譯 Docker 鏡像的 Dockerfile 寫法,感受下這種方式編譯的鏡像用起來如何。
這里準(zhǔn)備一個經(jīng)過 Maven 編譯后的普通的 springboot 項目來進(jìn)行 Docker 鏡像構(gòu)建,項目內(nèi)容如下圖所示,可以看到要用到的就是里面的應(yīng)用程序的 Jar 文件,將其存入鏡像內(nèi)完成鏡像構(gòu)建任務(wù)。
jar 文件大?。?0.86mb
<!-- ![](http://ww1.sinaimg.cn/large/007vhU0ely1g3kclm1mwkj30m805vt8m.jpg) -->
構(gòu)建 Docker 鏡像需要提前準(zhǔn)備 Dockerfile 文件,這個 Dockerfile 文件中的內(nèi)容為構(gòu)建 Docker 鏡像執(zhí)行的指令。下面是一個常用的 SpringBoot 構(gòu)建 Docker 鏡像的 Dockerfile,將它放入 Java 源碼目錄(target 的上級目錄),確保下面設(shè)置的 Dockerfile 腳本中設(shè)置的路徑和 target 路徑對應(yīng)。
FROM openjdk:8u212-b04-jre-slim VOLUME /tmp ADD target/*.jar app.jar RUN sh -c 'touch /app.jar' ENV JAVA_OPTS="-Duser.timezone=Asia/Shanghai" ENV APP_OPTS="" ENTRYPOINT [ "sh", "-c", "java $JAVA_OPTS -Djava.security.egd=file:/dev/./urandom -jar /app.jar $APP_OPTS" ]
通過 Docker build 命令構(gòu)建 Docker 鏡像,觀察編譯的時間。
由于后續(xù)需要將鏡像推送到 Aliyun Docker 倉庫,所以鏡像前綴用了 Aliyun。
time:此參數(shù)會顯示執(zhí)行過程經(jīng)過的時間
$ time docker build -t registry.cn-beijing.aliyuncs.com/mydlq/springboot:0.0.1 .
構(gòu)建過程
Sending build context to Docker daemon 148.7MB Step 1/7 : FROM openjdk:8u212-b04-jre-slim 8u212-b04-jre-slim: Pulling from library/openjdk 743f2d6c1f65: Already exists b83e581826a6: Pull complete 04305660f45e: Pull complete bbe7020b5561: Pull complete Digest: sha256:a5bcd678408a5fe94d13e486d500983ee6fa594940cbbe137670fbb90030456c Status: Downloaded newer image for openjdk:8u212-b04-jre-slim --->; 7c6b62cf60ee Step 2/7 : VOLUME /tmp --->; Running in 13a67ab65d2b Removing intermediate container 13a67ab65d2b --->; 52011f49ddef Step 3/7 : ADD target/*.jar app.jar --->; 26aa41a404fd Step 4/7 : RUN sh -c 'touch /app.jar' --->; Running in 722e7e44e04d Removing intermediate container 722e7e44e04d --->; 7baedb10ec62 Step 5/7 : ENV JAVA_OPTS="-Duser.timezone=Asia/Shanghai" --->; Running in 2681d0c5edac Removing intermediate container 2681d0c5edac --->; 5ef4a794b992 Step 6/7 : ENV APP_OPTS="" --->; Running in 5c8924a2a49d Removing intermediate container 5c8924a2a49d --->; fba87c19053a Step 7/7 : ENTRYPOINT [ "sh", "-c", "java $JAVA_OPTS -Djava.security.egd=file:/dev/./urandom -jar /app.jar $APP_OPTS" ] --->; Running in c4cf97009b3c Removing intermediate container c4cf97009b3c ---> d5f30cdfeb81 Successfully built d5f30cdfeb81 Successfully tagged registry.cn-beijing.aliyuncs.com/mydlq/springboot:0.0.1 real 0m13.778s user 0m0.078s sys 0m0.153s
看到這次編譯在 14s 內(nèi)完成。
將鏡像推送到 Aliyun 倉庫,然后查看并記錄推送時間
$ time docker push registry.cn-beijing.aliyuncs.com/mydlq/springboot:0.0.1
執(zhí)行過程
The push refers to repository [registry.cn-beijing.aliyuncs.com/mydlq/springboot] cc1a2376d7c0: Pushed 2b940d07e9e7: Pushed 9544e87fb8dc: Pushed feb5d0e1e192: Pushed 8fd22162ddab: Pushed 6270adb5794c: Pushed 0.0.1: digest: sha256:dc60d304383b1441941ca4e9abc08db775d7be57ccb7c534c929b34ff064a62f size: 1583 real 0m24.335s user 0m0.052s sys 0m0.059s
看到這次在 25s 內(nèi)完成。
這里切換到另一臺服務(wù)器上進(jìn)行鏡像拉取操作,觀察鏡像拉取時間。
$ time docker pull registry.cn-beijing.aliyuncs.com/mydlq/springboot:0.0.1
拉取過程
0.0.1: Pulling from mydlq/springboot 743f2d6c1f65: Already exists b83e581826a6: Pull complete 04305660f45e: Pull complete bbe7020b5561: Pull complete 4847672cbfa5: Pull complete b60476972fc4: Pull complete Digest: sha256:dc60d304383b1441941ca4e9abc08db775d7be57ccb7c534c929b34ff064a62f Status: Downloaded newer image for registry.cn-beijing.aliyuncs.com/mydlq/springboot:0.0.1 real 0m27.528s user 0m0.033s sys 0m0.192s
看到這次拉取總共用時 28s 內(nèi)完成。
這里將源碼的 JAVA 文件內(nèi)容修改,然后重新打 Jar 包,這樣再次嘗試編譯、推送、拉取過程,由于 Docker 在執(zhí)行構(gòu)建時會采用分層緩存,所以這是一個執(zhí)行較快過程。
(1)、編譯
$ time docker build -t registry.cn-beijing.aliyuncs.com/mydlq/springboot:0.0.2 . Sending build context to Docker daemon 148.7MB Step 1/7 : FROM openjdk:8u212-b04-jre-slim --->; 7c6b62cf60ee Step 2/7 : VOLUME /tmp --->; Using cache --->; 52011f49ddef Step 3/7 : ADD target/*.jar app.jar --->; c67160dd2a23 Step 4/7 : RUN sh -c 'touch /app.jar' --->; Running in 474900d843a2 Removing intermediate container 474900d843a2 --->; 3ce9a8bb2600 Step 5/7 : ENV JAVA_OPTS="-Duser.timezone=Asia/Shanghai" --->; Running in f48620b1ad36 Removing intermediate container f48620b1ad36 --->; 0478f8f14e5b Step 6/7 : ENV APP_OPTS="" --->; Running in 98485fb15fc8 Removing intermediate container 98485fb15fc8 --->; 0b567c848027 Step 7/7 : ENTRYPOINT [ "sh", "-c", "java $JAVA_OPTS -Djava.security.egd=file:/dev/./urandom -jar /app.jar $APP_OPTS" ] --->; Running in e32242fc6efe Removing intermediate container e32242fc6efe --->; 7b223b23ebfd Successfully built 7b223b23ebfd Successfully tagged registry.cn-beijing.aliyuncs.com/mydlq/springboot:0.0.2 real 0m3.190s user 0m0.039s sys 0m0.403s
可以看到在編譯鏡像過程中,前1、2層用的緩存,所以速度非常快。總編譯過程耗時 4s 內(nèi)完成。
(2)、推送
$ time docker push registry.cn-beijing.aliyuncs.com/mydlq/springboot:0.0.2 The push refers to repository [registry.cn-beijing.aliyuncs.com/mydlq/springboot] d66a2fec30b5: Pushed f4da2c7581aa: Pushed 9544e87fb8dc: Layer already exists feb5d0e1e192: Layer already exists 8fd22162ddab: Layer already exists 6270adb5794c: Layer already exists real 0m20.816s user 0m0.024s sys 0m0.081s
可以看到只推送了前兩層,其它四次由于遠(yuǎn)程倉庫未變化,所以沒有推送。整個推送過程耗時 21s 內(nèi)完成。
(3)、拉取
$ time docker pull registry.cn-beijing.aliyuncs.com/mydlq/springboot:0.0.2 0.0.2: Pulling from mydlq/springboot 743f2d6c1f65: Already exists b83e581826a6: Already exists 04305660f45e: Already exists bbe7020b5561: Already exists d7e364f0d94a: Pull complete 8d688ada35b1: Pull complete Digest: sha256:7c13c40fa92ec2fdc3a8dfdd3232be1be9c1a1a99bf123743ff2a43907ee03dc Status: Downloaded newer image for registry.cn-beijing.aliyuncs.com/mydlq/springboot:0.0.2 real 0m23.214s user 0m0.053s sys 0m0.097s
本地以及緩存前四層,只拉取有變化的后兩層。這個過程耗時 24s 內(nèi)完成。
通過這種方式對 SpringBoot 項目構(gòu)建 Docker 鏡像來使用,給我的感受就是只要源碼中發(fā)生一點(diǎn)點(diǎn)變化,那么 SpringBoot 項目就需要將項目經(jīng)過 Maven 編譯后再經(jīng)過 Docker 鏡像構(gòu)建,每次都會將一個 70M+ 的應(yīng)用 Jar 文件存入 Docker 中,有時候明明就改了一個字母,可能又得把整個程序 Jar 重新存入 Docker 鏡像中,然后在推送和拉取過程中,每次都得推一個大的鏡像或者拉取一個大的鏡像來進(jìn)行傳輸,感覺非常不方便。
Docker 為了節(jié)約存儲空間,所以采用了分層存儲概念。共享數(shù)據(jù)會對鏡像和容器進(jìn)行分層,不同鏡像可以共享相同數(shù)據(jù),并且在鏡像上為容器分配一個 RW 層來加快容器的啟動順序。
在構(gòu)建鏡像的過程中 Docker 將按照 Dockerfile 中指定的順序逐步執(zhí)行 Dockerfile 中的指令。隨著每條指令的檢查,Docker 將在其緩存中查找可重用的現(xiàn)有鏡像,而不是創(chuàng)建一個新的(重復(fù))鏡像。
Dockerfile 的每一行命令都創(chuàng)建新的一層,包含了這一行命令執(zhí)行前后文件系統(tǒng)的變化。為了優(yōu)化這個過程,Docker 使用了一種緩存機(jī)制:只要這一行命令不變,那么結(jié)果和上一次是一樣的,直接使用上一次的結(jié)果即可。
為了充分利用層級緩存,我們必須要理解 Dockerfile 中的命令行是如何工作的,尤其是RUN,ADD和COPY這幾個命令。
參考 Docker 文檔了解 Docker 鏡像緩存:https://docs.docker.com/develop/develop-images/dockerfile_best-practices/
SpringBoot 編譯成鏡像后,底層會是一個系統(tǒng),如 Ubantu,上一層是依賴的 JDK 層,然后才是 SpringBoot 層,最下面兩層我們無法操作,考慮優(yōu)化只能是 SpringBoot 層琢磨。
<!-- ![](http://ww1.sinaimg.cn/large/007vhU0ely1g3ko4fncrcj30m809s747.jpg) -->
從上面實驗中了解到之所以每次編譯、推送、拉取過程中較為緩慢,原因就是龐大的鏡像文件。了解到 Docker 緩存概念后就就產(chǎn)生一種想法,如果不經(jīng)常改變的文件緩存起來,將常改動的文件不進(jìn)行緩存。由于 SpringBoot 項目是經(jīng)常變換的,那么應(yīng)該怎么利用緩存機(jī)制來實現(xiàn)呢?如果強(qiáng)行利用緩存那么每次打的鏡像不都是緩存中的舊的程序內(nèi)容嗎。
所以就考慮一下應(yīng)用 Jar 包里面都包含了什么文件, Java 的哪些文件是經(jīng)常變動的,哪些不經(jīng)常變動,對此,下面將針對 SpringBoot 打的應(yīng)用 Jar 包進(jìn)行分析。
顯示解壓后的列表,查看各個文件夾大小
$ tree -L 3 --si --du . ├── [ 74M] BOOT-INF │ ├── [2.1k] classes │ └── [ 74M] lib ├── [ 649] META-INF │ ├── [ 552] MANIFEST.MF │ └── [ 59] maven └── [ 67] org └── [ 38] springframework
可以看到最大的文件就是 lib 這個文件夾,打開這個文件夾,里面是一堆相關(guān)依賴 Jar,這其中一個 Jar 不大,但是一堆 Jar 組合起來就非常大了,一般 SpringBoot 的項目依賴 Jar 大小維持在 40MB ~ 160MB。
<!-- ![](http://ww1.sinaimg.cn/large/007vhU0ely1g3kfz7x8ixj30m807a3yf.jpg) -->
在看看 org 文件夾,里面代碼加起來才幾百 KB。故此 SpringBoot 程序 Jar 包就是這些 Classes 文件和依賴的 Jar 組成,這些依賴 Jar 總共 74 MB,幾乎占了這個應(yīng)用 Jar 包的全部大小。
<!-- ![](http://ww1.sinaimg.cn/large/007vhU0ely1g3kj846ebej30m809ggln.jpg) -->
如果一個 Jar 包只包含 class 文件,那么這個 Jar 包的大小可能就幾百 KB。現(xiàn)在要探究一下,如果將 lib 依賴的 Jar 和 class 分離,設(shè)置應(yīng)用的 Jar 包只包含 class 文件,將 lib 文件夾下的 Jar 文件放在 SpringBoot Jar 的外面。
當(dāng)我們寫一個程序的時候,常常所依賴的 Jar 不會經(jīng)常變動,變動多的是源代碼程序,依賴的 Jar 包非常大而源代碼非常小。仔細(xì)思考一下,如果在打包成 Docker 鏡像的時候?qū)?yīng)用依賴的 Jar 包單獨(dú)設(shè)置一層緩存,而應(yīng)用 Jar 包只包含 Class 文件,這樣在 Docker 執(zhí)行編譯、推送、拉取過程中,除了第一次是全部都要執(zhí)行外,再往后的執(zhí)行編譯、推送、拉取過程中,只會操作改動的那個只包含 Class 的 Jar 文件,就幾百 KB,可以說是能夠瞬間完成這個過程。所以思考一下,如何將 lib 文件夾下的依賴 Jar 包和應(yīng)用 Jar 包分離開來。
<!-- ![](http://ww1.sinaimg.cn/large/007vhU0ely1g3kjd3ftf6j30m80cj3yn.jpg) -->
經(jīng)過查找很多相關(guān)資料,發(fā)現(xiàn) SpringBoot 的 Maven 插件在執(zhí)行 Maven 編譯打 Jar 包時候做了很多事情,如果改變某些插件的打包邏輯,致使打應(yīng)用 Jar 時候?qū)?lib 文件夾下所有的 Jar 包都拷貝到應(yīng)用 Jar 外面,只留下編譯好的字節(jié)碼文件。
將這幾個 Maven 工具引入到項目 pom.xml 中
<build> <plugins> <!--設(shè)置應(yīng)用 Main 參數(shù)啟動依賴查找的地址指向外部 lib 文件夾--> <plugin> <groupid>org.apache.maven.plugins</groupid> <artifactid>maven-jar-plugin</artifactid> <configuration> <archive> <manifest> <addclasspath>true</addclasspath> <classpathprefix>lib/</classpathprefix> </manifest> </archive> </configuration> </plugin> <!--設(shè)置 SpringBoot 打包插件不包含任何 Jar 依賴包--> <plugin> <groupid>org.springframework.boot</groupid> <artifactid>spring-boot-maven-plugin</artifactid> <configuration> <includes> <include> <groupid>nothing</groupid> <artifactid>nothing</artifactid> </include> </includes> </configuration> </plugin> <!--設(shè)置將 lib 拷貝到應(yīng)用 Jar 外面--> <plugin> <groupid>org.apache.maven.plugins</groupid> <artifactid>maven-dependency-plugin</artifactid> <executions> <execution> <id>copy-dependencies</id> <phase>prepare-package</phase> <goals> <goal>copy-dependencies</goal> </goals> <configuration> <outputdirectory>${project.build.directory}/lib</outputdirectory> </configuration> </execution> </executions> </plugin> </plugins> </build>
執(zhí)行 Maven 命令打包 Jar
$ mvn clean install
當(dāng) Maven 命令執(zhí)行完成后,查看 target 目錄如下圖:
<!-- ![](http://ww1.sinaimg.cn/large/007vhU0ely1g3kjnrap1rj30m8066747.jpg) -->
然后測試下這個 Jar 文件是否能正常運(yùn)行
$ java -jar springboot-helloworld-0.0.1.jar
然后看到運(yùn)行日志,OK!下面將繼續(xù)進(jìn)行 Dockerfile 改造工作。
<!-- ![](http://ww1.sinaimg.cn/large/007vhU0ely1g3koaq3ptpj30m809ggln.jpg) -->
> 項目 Github 地址:https://github.com/my-dlq/blog-example/tree/master/springboot-dockerfile
這里修改上面的 Dockerfile 文件,需要新增一層指令用于將 lib 目錄里面的依賴 Jar 復(fù)制到鏡像中,其它保持和上面 Dockerfile 一致。
FROM openjdk:8u212-b04-jre-slim VOLUME /tmp COPY target/lib/ ./lib/ ADD target/*.jar app.jar RUN sh -c 'touch /app.jar' ENV JAVA_OPTS="-Duser.timezone=Asia/Shanghai" ENV APP_OPTS="" ENTRYPOINT [ "sh", "-c", "java $JAVA_OPTS -Djava.security.egd=file:/dev/./urandom -jar /app.jar $APP_OPTS" ]
> 這里新增了一層指令,作用為將 lib 文件夾復(fù)制到鏡像之中,由于 Docker 緩存機(jī)制原因,這層一定要在復(fù)制應(yīng)用 Jar 之前,這樣改造后每次只要 lib/ 文件夾里面的依賴 Jar 不變,就不會新創(chuàng)建層,而是復(fù)用緩存。
在執(zhí)行編譯、推送、拉取之前,先將服務(wù)器上次鏡像相關(guān)的所有資源都清除掉,然后再執(zhí)行。
(1)、編譯
$ time docker build -t registry.cn-beijing.aliyuncs.com/mydlq/springboot:0.0.1 . Sending build context to Docker daemon 223.2MB Step 1/8 : FROM openjdk:8u212-b04-jre-slim 8u212-b04-jre-slim: Pulling from library/openjdk 743f2d6c1f65: Already exists b83e581826a6: Pull complete 04305660f45e: Pull complete bbe7020b5561: Pull complete Digest: sha256:a5bcd678408a5fe94d13e486d500983ee6fa594940cbbe137670fbb90030456c Status: Downloaded newer image for openjdk:8u212-b04-jre-slim --->; 7c6b62cf60ee Step 2/8 : VOLUME /tmp --->; Running in 529369acab24 Removing intermediate container 529369acab24 --->; ad689d937118 Step 3/8 : COPY target/lib/ ./lib/ --->; 029a64c15853 Step 4/8 : ADD target/*.jar app.jar --->; 6265a83a1b90 Step 5/8 : RUN sh -c 'touch /app.jar' --->; Running in 839032a58e6b Removing intermediate container 839032a58e6b --->; 5d877dc35b2b Step 6/8 : ENV JAVA_OPTS="-Duser.timezone=Asia/Shanghai" --->; Running in 4043994c5fed Removing intermediate container 4043994c5fed --->; 7cf32beb571f Step 7/8 : ENV APP_OPTS="" --->; Running in b7dcfa10458a Removing intermediate container b7dcfa10458a --->; b6b332bcf0e6 Step 8/8 : ENTRYPOINT [ "sh", "-c", "java $JAVA_OPTS -Djava.security.egd=file:/dev/./urandom -jar /app.jar $APP_OPTS" ] --->; Running in 539093461b59 Removing intermediate container 539093461b59 --->; d4c095c4ffec Successfully built d4c095c4ffec Successfully tagged registry.cn-beijing.aliyuncs.com/mydlq/springboot:0.0.1 real 0m22.983s user 0m0.051s sys 0m0.540s
(2)、推送
$ time docker push registry.cn-beijing.aliyuncs.com/mydlq/springboot:0.0.1 The push refers to repository [registry.cn-beijing.aliyuncs.com/mydlq/springboot] c16749205e05: Pushed 7fef1a146748: Pushed a3bae74bbdf2: Pushed 9544e87fb8dc: Pushed feb5d0e1e192: Pushed 8fd22162ddab: Pushed 6270adb5794c: Pushed 0.0.1: digest: sha256:e2f4db740880dbe5338b823112ba9467fedf8b27cd75572611d0d3837c80f157 size: 1789 real 0m30.335s user 0m0.052s sys 0m0.059s
(3)、拉取
$ time docker pull registry.cn-beijing.aliyuncs.com/mydlq/springboot:0.0.1 0.0.1: Pulling from mydlq/springboot 743f2d6c1f65: Already exists b83e581826a6: Pull complete 04305660f45e: Pull complete bbe7020b5561: Pull complete de6c4f15d75b: Pull complete 7066947b7d89: Pull complete e0742de67c75: Pull complete Digest: sha256:e2f4db740880dbe5338b823112ba9467fedf8b27cd75572611d0d3837c80f157 Status: Downloaded newer image for registry.cn-beijing.aliyuncs.com/mydlq/springboot:0.0.1 real 0m36.585s user 0m0.024s sys 0m0.092s
(1)、編譯
$ time docker build -t registry.cn-beijing.aliyuncs.com/mydlq/springboot:0.0.2 . Sending build context to Docker daemon 223.2MB Step 1/8 : FROM openjdk:8u212-b04-jre-slim --->; 7c6b62cf60ee Step 2/8 : VOLUME /tmp --->; Using cache --->; ad689d937118 Step 3/8 : COPY target/lib/ ./lib/ --->; Using cache --->; 029a64c15853 Step 4/8 : ADD target/*.jar app.jar --->; 563773953844 Step 5/8 : RUN sh -c 'touch /app.jar' --->; Running in 3b9df57802bd Removing intermediate container 3b9df57802bd --->; 706a0d47317f Step 6/8 : ENV JAVA_OPTS="-Duser.timezone=Asia/Shanghai" --->; Running in defda61452bf Removing intermediate container defda61452bf --->; 742c7c926374 Step 7/8 : ENV APP_OPTS="" --->; Running in f09b81d054dd Removing intermediate container f09b81d054dd --->; 929ed5f8b12a Step 8/8 : ENTRYPOINT [ "sh", "-c", "java $JAVA_OPTS -Djava.security.egd=file:/dev/./urandom -jar /app.jar $APP_OPTS" ] --->; Running in 5dc66a8fc1e6 Removing intermediate container 5dc66a8fc1e6 --->; c4942b10992c Successfully built c4942b10992c Successfully tagged registry.cn-beijing.aliyuncs.com/mydlq/springboot:0.0.2 real 0m2.524s user 0m0.051s sys 0m0.493s
可以看到,這次在第 3 層直接用的緩存,整個編譯過程才花了 2.5 秒時間
(2)、推送
$ time docker push registry.cn-beijing.aliyuncs.com/mydlq/springboot:0.0.2 The push refers to repository [registry.cn-beijing.aliyuncs.com/mydlq/springboot] d719b9540809: Pushed d45bf4c5fb92: Pushed a3bae74bbdf2: Layer already exists 9544e87fb8dc: Layer already exists feb5d0e1e192: Layer already exists 8fd22162ddab: Layer already exists 6270adb5794c: Layer already exists 0.0.2: digest: sha256:b46d81b153ec64321caaae7ab28da0e362ed7d720a7f0775ea8d1f7bef310d00 size: 1789 real 0m0.168s user 0m0.016s sys 0m0.032s
可以看到在 0.2s 內(nèi)就完成了鏡像推送
(3)、拉取
$ time docker pull registry.cn-beijing.aliyuncs.com/mydlq/springboot:0.0.2 0.0.2: Pulling from mydlq/springboot 743f2d6c1f65: Already exists b83e581826a6: Already exists 04305660f45e: Already exists bbe7020b5561: Already exists de6c4f15d75b: Already exists 1c77cc70cc41: Pull complete aa5b8cbca568: Pull complete Digest: sha256:b46d81b153ec64321caaae7ab28da0e362ed7d720a7f0775ea8d1f7bef310d00 Status: Downloaded newer image for registry.cn-beijing.aliyuncs.com/mydlq/springboot:0.0.2 real 0m1.947s user 0m0.017s sys 0m0.042s
可以看到在 2s 內(nèi)就完成了鏡像拉取
由于網(wǎng)絡(luò)波動和系統(tǒng)變化,所以時間只能當(dāng)做參考,不過執(zhí)行編譯、推送、拉取過程的確快了不少,大部分用文件都進(jìn)行了緩存,只有幾百 KB 的流量交互自然速度比幾十 MB 甚至幾百 MB 速度要快很多。
最后說明一下,這種做法只是提供了一種參考,現(xiàn)在的微服務(wù)服務(wù) Docker 鏡像化以來,維護(hù)的是整個鏡像而不是一個服務(wù)程序,所以關(guān)心的是 Docker 鏡像能否能正常運(yùn)行,怎么構(gòu)建鏡像會使構(gòu)建的鏡像更好用。
在生產(chǎn)環(huán)境下由于版本變化較慢,不會動不動就更新,所以在生產(chǎn)環(huán)境下暫時最好還是按部就班,應(yīng)用原來 SpringBoot 鏡像編譯方式以確保安裝(除非已大量實例驗證該構(gòu)建方法)。
“Java SpringBoot項目怎么構(gòu)建Docker鏡像調(diào)優(yōu)”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識可以關(guān)注億速云網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實用文章!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。