最近學習瞭解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打包。