最近学习了解graalvm
, 但环境安装麻烦,所以想着还是用docker一站式解决,特此记录一下使用docker打包编译spring-boot-native的过程
spring-boot 代码
直接从 https://start.spring.io/ 生成就可以用了
基础docker 镜像
先看看有没有人已经准备打包好的graalvm
镜像,在hub.docker.com 搜索 graalvm,findepi/graalvm文档多点,再看IMAGE LAYERS
基本符合要求,就用这个吧。
# 已包含graalvm-jdk 以及 gu install native-image
docker pull findepi/graalvm:java11-native
打包编译
spring-boot 代码
我先在mac上进行编译打包
# 先打包,平时怎么做,现在就怎么做
mvn clean package
# 然后弄成 native-image
docker run -it --rm -v "$PWD":/tmp -w /tmp findepi/graalvm:java11-native native-image -jar demo.jar
报错了,说找不到启动类,解压 demo.jar 发现,启动类的class路径是被包了一层的
参考start.spring.io生成代码里的help.md
理论上可以了,但我的电脑是mac m1芯片
,执行一半就卡主了- -、
换win10
直接执行
> docker run -it --rm -v "$PWD":/tmp -w /tmp findepi/graalvm:java11-native
docker: invalid reference format.
See 'docker run --help'.
# 出错了,我怀疑是 $PWD 不支持,但echo $PWD 是正常。
因docker desktop 是直接直接运行镜像并挂载目录,所以我直接换了个方式
然后在进入命令行模式
开始编译打包
因这个镜像内没有maven,所以直接用了mvnw
mvnw
是Maven Wrapper的缩写。因为我们安装Maven时,默认情况下,系统所有项目都会使用全局安装的这个Maven版本。但是,对于某些项目来说,它可能必须使用某个特定的Maven版本,这个时候,就可以使用Maven Wrapper,它可以负责给这个特定的项目安装指定版本的Maven,而其他项目不受影响。https://www.liaoxuefeng.com/wiki/1252599548343744/1305148057976866
#1. 打包
./mvnw clan package
#2. native image
./mvnw package -Pnative
顺利执行,然后就是测试,如下图的测试
启动时间的差距还是明显的,native 0.167s,jave -jar的方式是 2.175s
如果项目比较大的话,时间差距应该会更大
这是在docker中启动,限制是CPUs:8 Memory:12.00 GB
打出的native-image只能在Linux启动,win10下无法启动
总结
-
native 启动是真的快,毕竟是二进制文件,少了字节码转机器码的过程,但打包过程是真的慢,用了07:13 min
如果生产环境的项目也可以瞬间启动,还是有点吸引人的,但动态代理需要配置就很麻烦。目前spring-boot-native还处于实现性质,期待他的release版本
-
mac m1 芯片在使用docker还是有奇奇怪怪的问题,使用win10就是
一把过
-
docker 打包原理,就是把项目目录挂在到容器中,可以参考docker maven打包。