简介

在文章《GraalVM和Spring Native尝鲜,一步步让Springboot启动飞起来,66ms完成启动》中,我们介绍了如何使用Spring Native和buildtools插件,打包出本地镜像,也打包成Docker镜像。本文探索一下,如果不通过这个插件来生成镜像。这样我们可以控制更多、了解更多。

创建Spring Boot项目

创建Spring Boot项目,引入Spring Native,我们主要使用的是Spring Native提供的AOT功能。如下:

<dependencies>
<dependency>
<groupId>org.springframework.experimental</groupId>
<artifactId>spring-native</artifactId>
<version>${spring-native.version}</version>
</dependency> <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies> <build>
<plugins>
<plugin>
<groupId>org.springframework.experimental</groupId>
<artifactId>spring-aot-maven-plugin</artifactId>
<version>${spring-native.version}</version>
<executions>
<execution>
<id>test-generate</id>
<goals>
<goal>test-generate</goal>
</goals>
</execution>
<execution>
<id>generate</id>
<goals>
<goal>generate</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>

Build image的时候,我们需要引用依赖库,所以加上下面的插件:

<plugin>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/lib</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>

接着先编译出Java class,命令如下:

$ mvn clean package

打包本地镜像

前面的命令打包完,在target目录下会有一个lib目录,我们需要用上。通过native-image命令来生成镜像,如下:

$ native-image -cp ./target/classes/:target/lib/* com.pkslow.springboot.SpringbootGraalVMNativeMain Pkslow.SpringbootGraalVMNativeMain

这样就会生成一个可执行文件:Pkslow.SpringbootGraalVMNativeMain

执行如下:

$ ./Pkslow.SpringbootGraalVMNativeMain

使用了93ms来启动,还是很快的。

访问服务是正常的:

$ curl -i http://localhost:8080/hi-graalvm
HTTP/1.1 200
Content-Type: text/plain;charset=UTF-8
Content-Length: 67
Date: Wed, 02 Nov 2022 15:08:44 GMT This message is from Spring Boot built/run by GraalVM/Spring Native

创建Docker镜像

先拉取基础镜像:

$ docker pull springci/graalvm-ce:java11-0.12.x

进入容器看一下里面的状况:

$ docker run -it --rm --entrypoint bash springci/graalvm-ce:java11-0.12.x
root@d9b54bdce70a:/# pwd
/
root@d9b54bdce70a:/# java --version
openjdk 11.0.15 2022-04-19
OpenJDK Runtime Environment GraalVM 22.1.1.0-dev (build 11.0.15+10-jvmci-22.1-b06)
OpenJDK 64-Bit Server VM GraalVM 22.1.1.0-dev (build 11.0.15+10-jvmci-22.1-b06, mixed mode, sharing)
root@d9b54bdce70a:/# which java
/opt/java/bin/java
root@d9b54bdce70a:/# which native-image
/opt/java/bin/native-image

准备一下Dockerfile如下:

FROM springci/graalvm-ce:java11-0.12.x
VOLUME /tmp ARG PORT=8080
ARG TIME_ZONE=Asia/Shanghai ENV TZ=${TIME_ZONE}
EXPOSE ${PORT}
RUN pwd RUN mkdir /pkslow-application
WORKDIR /pkslow-application/
RUN cd /pkslow-application
COPY target/classes/ /pkslow-application/classes/
COPY target/lib/ /pkslow-application/lib/ RUN native-image -cp /pkslow-application/classes/:/pkslow-application/lib/* \
com.pkslow.springboot.SpringbootGraalVMNativeMain \
Pkslow.SpringbootGraalVMNativeMain ENTRYPOINT ["/pkslow-application/Pkslow.SpringbootGraalVMNativeMain"]

打包Docker镜像:

$ docker build . -t pkslow/spring-boot-native-without-buildtools:1.0-SNAPSHOT -f src/main/dker/Dockerfile

完成后通过下面命令启动,57ms完成启动:

$ docker run -it -p 8080:8080 --rm pkslow/spring-boot-native-without-buildtools:0-SNAPSHOT
2022-11-02 23:48:40.918 INFO 1 --- [ main] o.s.nativex.NativeListener : AOT mode enabled . ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.6.2) 2022-11-02 23:48:40.920 INFO 1 --- [ main] c.p.s.SpringbootGraalVMNativeMain : Starting SpringbootGraalVMNativeMain using Java 11.0.15 on 12528bd45fd7 with PID 1 (/pkslow-application/Pkslow.SpringbootGraalVMNativeMain started by root in /pkslow-application)
2022-11-02 23:48:40.920 INFO 1 --- [ main] c.p.s.SpringbootGraalVMNativeMain : No active profile set, falling back to default profiles: default
2022-11-02 23:48:40.934 INFO 1 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8080 (http)
2022-11-02 23:48:40.935 INFO 1 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
2022-11-02 23:48:40.935 INFO 1 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/9.0.56]
2022-11-02 23:48:40.940 INFO 1 --- [ main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2022-11-02 23:48:40.940 INFO 1 --- [ main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 19 ms
2022-11-02 23:48:40.963 INFO 1 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path ''
2022-11-02 23:48:40.964 INFO 1 --- [ main] c.p.s.SpringbootGraalVMNativeMain : Started SpringbootGraalVMNativeMain in 0.057 seconds (JVM running for 0.061)
2022-11-02 23:48:57.098 INFO 1 --- [nio-8080-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring DispatcherServlet 'dispatcherServlet'
2022-11-02 23:48:57.098 INFO 1 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Initializing Servlet 'dispatcherServlet'
2022-11-02 23:48:57.098 INFO 1 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Completed initialization in 0 ms

测试正常启动:

$ curl -i http://127.0.0.1:8080/hi-graalvm
HTTP/1.1 200
Content-Type: text/plain;charset=UTF-8
Content-Length: 67
Date: Wed, 02 Nov 2022 15:49:05 GMT This message is from Spring Boot built/run by GraalVM/Spring Native

为了集成打包镜像到CI/CD中,在pom添加以下插件:

<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>3.0.0</version>
<executions>
<execution>
<phase>install</phase>
<goals>
<goal>exec</goal>
</goals>
<configuration>
<skip>${docker.skip}</skip>
<executable>docker</executable>
<arguments>
<argument>build</argument>
<argument>.</argument>
<argument>-t</argument>
<argument>pkslow/${project.artifactId}:${project.version}</argument>
<argument>-f</argument>
<argument>src/main/docker/Dockerfile</argument>
</arguments>
</configuration>
</execution>
</executions>
</plugin>

通过以下命令即可生成Docker镜像:

$ mvn clean install -Ddocker.skip=false

代码

代码请看GitHub: https://github.com/LarryDpk/pkslow-samples

最新文章

  1. linux 下安装mongodb
  2. mybatis如何做分页处理
  3. JAVA 汇编语言查看
  4. Autofac的注入和web.config配合
  5. ORM中去除反射,添加Expression
  6. edge animate从入门到放弃
  7. 详解Google Chrome浏览器(操作篇)(下)
  8. 转义字符及URI编码
  9. poj3237 树链部分 边权模板
  10. Spring获取bean的步骤
  11. tcp.go
  12. Unnamed namespaces
  13. IIC 设备使用
  14. Apex简介
  15. Html引入百度富文本编辑器ueditor
  16. python --- 18 类与类之间的关系, 特殊成员
  17. UVa 12003 Array Transformer (分块)
  18. nginx正确服务react-router应用
  19. CodeFirst中DbContext动态添加DbSet
  20. 树莓派 Learning 002 装机后必要的操作 --- 10 实现本地电脑与远程桌面之间复制粘贴(传输)文件

热门文章

  1. Codeforces 1670 E. Hemose on the Tree
  2. VUE学习2
  3. MQTT GUI 客户端 可视化管理工具推荐
  4. 字符编码 XUTF
  5. Cacheable VS Non-Cacheable
  6. python基础语法/简单数据类型/常量与变量
  7. 【JVM调优】Day01:Garbage的概念、垃圾回收的算法(标记清除、拷贝、标记压缩)、各种垃圾回收器(Serial、Parallel、CMS并发)及存在的问题
  8. 【RocketMQ】主从同步实现原理
  9. 3A锂电池充电管理芯片PW4035
  10. go-carbon 1.5.3 版本发布, 修复已知 bug 和新增俄罗斯语翻译文件