自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

使用Spring Boot創(chuàng)建docker image

開(kāi)發(fā) 前端
今天我們來(lái)體驗(yàn)一下Spring Boot 2.3.3 帶來(lái)的快速創(chuàng)建docker image的功能。

 簡(jiǎn)介
在很久很久以前,我們是怎么創(chuàng)建Spring Boot的docker image呢?最最通用的辦法就是將Spring boot的應(yīng)用程序打包成一個(gè)fat jar,然后寫(xiě)一個(gè)docker file,將這個(gè)fat jar制作成為一個(gè)docker image然后運(yùn)行。

今天我們來(lái)體驗(yàn)一下Spring Boot 2.3.3 帶來(lái)的快速創(chuàng)建docker image的功能。

傳統(tǒng)做法和它的缺點(diǎn)
現(xiàn)在我們創(chuàng)建一個(gè)非常簡(jiǎn)單的Spring Boot程序:

  1. @SpringBootApplication 
  2. @RestController 
  3. public class Application { 
  4.  
  5.     public static void main(String[] args) { 
  6.         SpringApplication.run(Application.class, args); 
  7.     } 
  8.  
  9.     @GetMapping("/getInfo"
  10.     public String getInfo() { 
  11.         return "www.flydean.com"
  12.     } 
  13. 復(fù)制代碼 

默認(rèn)情況下,我們build出來(lái)的是一個(gè)fat jar:springboot-with-docker-0.0.1-SNAPSHOT.jar

我們解壓看一下它的內(nèi)容:

Spring boot的fat jar分為三個(gè)部分,第一部分就是BOOT-INF, 里面的class目錄放的是我們自己編寫(xiě)的class文件。而lib目錄存放的是項(xiàng)目依賴(lài)的其他jar包。

第二部分是META-INF,里面定義了jar包的屬性信息。

第三部分是Spring Boot的類(lèi)加載器,fat jar包的啟動(dòng)是通過(guò)Spring Boot的jarLauncher來(lái)創(chuàng)建LaunchedURLClassLoader,通過(guò)它來(lái)加載lib下面的jar包,最后以一個(gè)新線(xiàn)程啟動(dòng)應(yīng)用的Main函數(shù)。

這里不多講Spring Boot的啟動(dòng)。

我們看一下,如果想要用這個(gè)fat jar來(lái)創(chuàng)建docker image應(yīng)該怎么寫(xiě):

  1. FROM openjdk:8-jdk-alpine 
  2. EXPOSE 8080 
  3. ARG JAR_FILE=target/springboot-with-docker-0.0.1-SNAPSHOT.jar 
  4. ADD ${JAR_FILE} app.jar 
  5. ENTRYPOINT ["java","-jar","/app.jar"
  6. 復(fù)制代碼 

這樣寫(xiě)有兩個(gè)問(wèn)題。

第一個(gè)問(wèn)題:我們是用的far jar,在使用far jar的過(guò)程中會(huì)有一定的性能問(wèn)題,肯定要比解壓過(guò)后的性能要低,尤其是在容器環(huán)境中運(yùn)行的情況下,可能會(huì)更加突出。

第二個(gè)問(wèn)題:我們知道docker的image是按layer來(lái)構(gòu)建的,按layer構(gòu)建的好處就是可以減少image構(gòu)建的時(shí)間和重用之前的layer。

但是如果使用的是fat jar包,即使我們只修改了我們自己的代碼,也會(huì)導(dǎo)致整個(gè)fat jar重新更新,從而影響docker image的構(gòu)建速度。

使用Buildpacks
傳統(tǒng)的辦法除了有上面的兩個(gè)問(wèn)題,還有一個(gè)就是需要自己構(gòu)建docker file,有沒(méi)有一鍵構(gòu)建docker image的方法呢?

答案是肯定的。

Spring Boot在2.3.0之后,引入了Cloud Native 的buildpacks,通過(guò)這個(gè)工具,我們可以非常非常方便的創(chuàng)建docker image。

在Maven和Gradle中,Spring Boot引入了新的phase: spring-boot:build-image

我們可以直接運(yùn)行:

  1. mvn  spring-boot:build-image 
  2. 制代碼 

運(yùn)行之,很不幸的是,你可能會(huì)遇到下面的錯(cuò)誤:

  1. [ERROR] Failed to execute goal org.springframework.boot:spring-boot-maven-plugin:2.3.3.RELEASE:build-image (default-cli) on project springboot-with-docker: Execution default-cli of goal org.springframework.boot:spring-boot-maven-plugin:2.3.3.RELEASE:build-image failed: Docker API call to 'localhost/v1.24/images/create?fromImage=gcr.io%2Fpaketo-buildpacks%2Fbuilder%3Abase-platform-api-0.3' failed with status code 500 "Internal Server Error" and message "Get https://gcr.io/v2/: net/http: request canceled while waiting for connection (Client.Timeout exceeded while awaiting headers)" -> [Help 1] 
  2. 復(fù)制代碼 

這是因?yàn)槲覀儫o(wú)法從gcr.io中拉取鏡像!

沒(méi)關(guān)系,如果你會(huì)正確的上網(wǎng)方式的話(huà),那么我估計(jì)你已經(jīng)找到了一個(gè)代理。

將你的代理配置到Docker的代理項(xiàng)里面,我使用的是Docker desktop,下面是我的配置:

重新運(yùn)行 mvn spring-boot:build-image

等待執(zhí)行結(jié)果:

  1. [INFO] --- spring-boot-maven-plugin:2.3.3.RELEASE:build-image (default-cli) @ springboot-with-docker --- 
  2. [INFO] Building image 'docker.io/library/springboot-with-docker:0.0.1-SNAPSHOT' 
  3. [INFO]  
  4. [INFO]  > Pulling builder image 'gcr.io/paketo-buildpacks/builder:base-platform-api-0.3' 0% 
  5. [INFO]  > Pulling builder image 'gcr.io/paketo-buildpacks/builder:base-platform-api-0.3' 0% 
  6. [INFO]  > Pulling builder image 'gcr.io/paketo-buildpacks/builder:base-platform-api-0.3' 0% 
  7. [INFO]  > Pulling builder image 'gcr.io/paketo-buildpacks/builder:base-platform-api-0.3' 0% 
  8. [INFO]  > Pulling builder image 'gcr.io/paketo-buildpacks/builder:base-platform-api-0.3' 0% 
  9. [INFO]  > Pulling builder image 'gcr.io/paketo-buildpacks/builder:base-platform-api-0.3' 0% 
  10. 復(fù)制代碼 

你可以看到,我們的確是需要從gcr.io拉取image。

Layered Jars
如果你不想使用Cloud Native Buildpacks,還是想使用傳統(tǒng)的Dockerfile。 沒(méi)關(guān)系,SpringBoot為我們提供了獨(dú)特的分層jar包系統(tǒng)。

怎么開(kāi)啟呢? 我們需要在POM文件中加上下面的配置:

  1. <build> 
  2.        <plugins> 
  3.            <plugin> 
  4.                <groupId>org.springframework.boot</groupId> 
  5.                <artifactId>spring-boot-maven-plugin</artifactId> 
  6.                <configuration> 
  7.                    <layers> 
  8.                        <enabled>true</enabled> 
  9.                    </layers> 
  10.                </configuration> 
  11.            </plugin> 
  12.        </plugins> 
  13.    </build> 
  14. 制代碼 

再次打包,看下jar包的內(nèi)容:

看起來(lái)和之前的jar包沒(méi)什么不同,只不過(guò)多了一個(gè)layers.idx 這個(gè)index文件:

  1. "dependencies"
  2.   - "BOOT-INF/lib/" 
  3. "spring-boot-loader"
  4.   - "org/" 
  5. "snapshot-dependencies"
  6. "application"
  7.   - "BOOT-INF/classes/" 
  8.   - "BOOT-INF/classpath.idx" 
  9.   - "BOOT-INF/layers.idx" 
  10.   - "META-INF/" 
  11. 復(fù)制代碼 

index文件主要分為4個(gè)部分:

  • dependencies - 非SNAPSHOT的依賴(lài)jar包
  • snapshot-dependencies - SNAPSHOT的依賴(lài)jar包
  • spring-boot-loader - Spring boot的class loader文件
  • application - 應(yīng)用程序的class和resources文件

注意,這里的index文件是有順序的,它和我們將要添加到docker image中的layer順序是一致的。

最少變化的將會(huì)最先添加到layer中,變動(dòng)最大的放在最后面的layer。

我們可以使用layertools jarmode來(lái)對(duì)生成的fat jar進(jìn)行校驗(yàn)或者解壓縮:

  1. java -Djarmode=layertools -jar springboot-with-docker-0.0.1-SNAPSHOT.jar  
  2. Usage: 
  3.   java -Djarmode=layertools -jar springboot-with-docker-0.0.1-SNAPSHOT.jar 
  4.  
  5. Available commands: 
  6.   list     List layers from the jar that can be extracted 
  7.   extract  Extracts layers from the jar for image creation 
  8.   help     Help about any command 
  9. 復(fù)制代碼 

使用list命令,我們可列出jar包中的layer信息。使用extract我們可以解壓出不同的layer。

我們執(zhí)行下extract命令,看下結(jié)果:

可以看到,我們根據(jù)layers.idx解壓出了不同的文件夾。

我們看一下使用layer的dockerFile應(yīng)該怎么寫(xiě):

  1. FROM adoptopenjdk:11-jre-hotspot as builder 
  2. WORKDIR application 
  3. ARG JAR_FILE=target/*.jar 
  4. COPY ${JAR_FILE} application.jar 
  5. RUN java -Djarmode=layertools -jar application.jar extract 
  6.  
  7. FROM adoptopenjdk:11-jre-hotspot 
  8. WORKDIR application 
  9. COPY --from=builder application/dependencies/ ./ 
  10. COPY --from=builder application/spring-boot-loader/ ./ 
  11. COPY --from=builder application/snapshot-dependencies/ ./ 
  12. COPY --from=builder application/application/ ./ 
  13. ENTRYPOINT ["java""org.springframework.boot.loader.JarLauncher"
  14. 復(fù)制代碼 

這樣我們的一個(gè)分層的DockerImage就創(chuàng)建完成了。

自定義Layer
如果我們需要自定義Layer該怎么做呢?

我們可以創(chuàng)建一個(gè)獨(dú)立的layers.xml文件:

  1. <layers xmlns="http://www.springframework.org/schema/boot/layers" 
  2.         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
  3.         xsi:schemaLocation="http://www.springframework.org/schema/boot/layers 
  4.               https://www.springframework.org/schema/boot/layers/layers-2.3.xsd"> 
  5.     <application> 
  6.         <into layer="spring-boot-loader"
  7.             <include>org/springframework/boot/loader/**</include> 
  8.         </into
  9.         <into layer="application" /> 
  10.     </application> 
  11.     <dependencies> 
  12.         <into layer="snapshot-dependencies"
  13.             <include>*:*:*SNAPSHOT</include> 
  14.         </into
  15.         <into layer="company-dependencies"
  16.             <include>com.flydean:*</include> 
  17.         </into
  18.         <into layer="dependencies"/> 
  19.     </dependencies> 
  20.     <layerOrder> 
  21.         <layer>dependencies</layer> 
  22.         <layer>spring-boot-loader</layer> 
  23.         <layer>snapshot-dependencies</layer> 
  24.         <layer>company-dependencies</layer> 
  25.         <layer>application</layer> 
  26.     </layerOrder> 
  27. </layers> 
  28. 復(fù)制代碼 

怎么使用這個(gè)layer.xml呢?

添加到build plugin中就可以了:

  1. <build> 
  2.        <plugins> 
  3.            <plugin> 
  4.                <groupId>org.springframework.boot</groupId> 
  5.                <artifactId>spring-boot-maven-plugin</artifactId> 
  6.                <configuration> 
  7.                    <layers> 
  8.                        <enabled>true</enabled> 
  9.                        <configuration>${project.basedir}/src/main/resources/layers.xml</configuration> 
  10.                    </layers> 
  11.                </configuration> 
  12.            </plugin> 
  13.        </plugins> 
  14.    </build> 

 

責(zé)任編輯:姜華 來(lái)源: 今日頭條
相關(guān)推薦

2023-05-11 12:40:00

Spring控制器HTTP

2022-10-10 08:00:00

微服務(wù)Spring Boo容器

2023-10-25 18:08:13

應(yīng)用容器化Docker

2024-01-18 07:53:37

2013-01-14 11:33:00

IBMdW

2024-02-22 18:12:18

微服務(wù)架構(gòu)設(shè)計(jì)模式

2023-12-02 18:32:32

SpringDocker鏡像

2022-06-28 15:04:32

容器Docker

2022-06-28 15:06:35

容器Spring

2023-10-06 23:40:49

Spring開(kāi)發(fā)

2024-08-14 17:02:22

Docker容器

2021-03-01 23:26:41

日志Spring BootAOP

2021-11-04 09:00:00

JavaSpring BootURL

2021-05-07 07:03:33

Spring打包工具

2020-11-12 07:51:05

DockerSpring Boot應(yīng)用

2022-02-09 20:39:52

Actuator應(yīng)用監(jiān)控

2021-09-15 16:20:02

Spring BootFilterJava

2017-03-23 09:29:06

2024-04-18 09:34:28

Reactor項(xiàng)目異步編程

2023-02-27 08:09:42

SpringAOP代理
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)