将Spring Boot转换为GraalVM原生镜像,使用spring-graal-native
这篇文章是ZOZO Technologies #4 Advent Calendar 2019第4天的文章。
昨天是@ikeponsu的《使用GAS创建Google Drive监控系统》。
在本文中,我们使用一个实验性项目称为spring-graal-native,通过创建GraalVM本机镜像来比较Spring Boot应用程序的速度。
首先
2019年11月21日,GraalVM 19.3.0发布了。不仅仅是Java程序员,我相信所有使用JVM的人都非常关注GraalVM的未来,难道只有我一个人吗?此外,于10月7日至10日举行的SpringOne Platform 2019会议上,YouTube上有一个非常有趣的演讲视频,名为”将Spring Boot应用作为GraalVM本地映像运行”。简单来说,它介绍了一个实验性的项目spring-graal-native,将Spring Boot应用转换为GraalVM本地映像,并进行了性能比较。在本文中,我将介绍这个视频中展示的spring-graal-native,并对Spring Boot应用程序进行GraalVM本地映像的转换,以进行速度比较。
关于Spring Framework的GraalVM原生映像支持
在进入本题之前,请确认一下Spring Framework的GraalVM支持情况。
目前最新的版本是Spring Framework 5.2.1。在Spring Framework 5.1时开始支持GraalVM原生镜像,但遇到了很多问题,在Spring Framework 5.2中仍在解决这些问题。因此,Spring Framework的GraalVM原生镜像支持可能会在Spring Framework 5.3中推出。
详细信息请参考Spring Framework的GraalVM原生镜像支持维基。
环境
本文所使用的环境进行了以下操作的确认。
WSL 18.04
GraalVM CE 19.2.0.1
Spring Boot 2.2
Java8
由于GraalVM在Windows上还没有正式发布,所以我选择使用WSL进行尝试。
下载
首先需要下载的东西。
-
- spring-graal-native
- GraalVM
首先,克隆spring-projects-experimental的spring-graal-native。
该项目属于Spring的实验性项目,并不是正式版本。请务必在生产环境等使用时谨慎操作。
$ git clone https://github.com/spring-projects-experimental/spring-graal-native.git
接下来,下载并解压GraalVM 19.2.0.1。
当前最新版本为19.3,但我们将使用GraalVM 19.2.0.1。
下载链接:graalvm-ce-linux-amd64-19.2.0.1.tar.gz。
$ tar -xvf graalvm-ce-linux-amd64-19.2.0.1.tar.gz
安装/设置
我们要进行GraalVM的设置。
首先,我们要将路径添加到可使用gu命令。
$ export PATH=/home/tkani/graalvm/graalvm-ce-19.2.0.1/bin:$PATH
$ gu
GraalVM Component Updater v2.0.0
Usage:
gu info [-clLprstuvV] <param> prints info about specific component (from file, URL or catalog)
gu available [-alvV] <expr> lists components available in catalog
gu install [-0cfiLnorvyxY] <param> installs a component package
gu list [-clv] <expression> lists installed components, or components from catalog
gu remove [-0fxv] <id> uninstalls a component
gu update [-x] [<ver>] [<param>] upgrades to recent GraalVM
gu rebuild-images rebuilds native images. Use -h for detailed usage
・・・・
使用gu命令安装native-image命令。
$ gu install native-image
Downloading: Component catalog from www.graalvm.org
Processing component archive: Native Image
Downloading: Component native-image: Native Image from github.com
Installing new component: Native Image (org.graalvm.native-image, version 19.2.0.1)
$ native-image --version
GraalVM Version 19.2.0.1 CE
创建GraalVM本机映像。
当使用native-image命令后,我将尝试将克隆的Spring Boot应用程序转换为GraalVM本机映像。该步骤在spring-graal-native的README中有详细说明。
$ cd /home/tkani/graalvm/spring-graal-native/spring-graal-native-feature
$ ./mvnw clean package
在这里,我们将在commandlinerunner目录中运行compile.sh,而spring-graal-native-samples目录下有各种项目可供使用。
$ cd /home/tkani/graalvm/spring-graal-native/spring-graal-native-samples
$ ls -l
终于执行compile.sh以创建GraalVM原生镜像。
$ cd /home/tkani/graalvm/spring-graal-native/spring-graal-native-samples
$ cd commandlinerunner
$ ./compile.sh
・・・エラー部分のみ抜粋・・・
Compiled app (clr)
./compile.sh: line 39: ./clr: No such file or directory
・・・
运行compile.sh时出现错误。。。
经过调查发现,需要安装一个叫zlib1g-dev的压缩库。
$ sudo apt install zlib1g-dev
這個部落格對我來說非常有參考價值。非常感謝。能夠在GraalVM上運行Rust和進行本地編譯光線追踪。
比较处理时间
很好,GraalVM的本地映像clr已经完成了。现在让我们来比较一下Spring Boot的jar包与GraalVM本地映像的速度。
Spring Boot应用程序的运行时间是1.784秒。
$ time java -jar ./target/commandlinerunner-0.0.1-SNAPSHOT.jar
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.2.0.RELEASE)
2019-12-03 14:03:26.803 INFO 1061 --- [ main] c.e.c.CommandlinerunnerApplication : Starting CommandlinerunnerApplication v0.0.1-SNAPSHOT on ST180329 with PID 1061 (/home/tkani/graalvm/spring-graal-native/spring-graal-native-samples/commandlinerunner/target/commandlinerunner-0.0.1-SNAPSHOT.jar started by tkani in /home/tkani/graalvm/spring-graal-native/spring-graal-native-samples/commandlinerunner)
2019-12-03 14:03:26.808 INFO 1061 --- [ main] c.e.c.CommandlinerunnerApplication : No active profile set, falling back to default profiles: default
2019-12-03 14:03:27.298 INFO 1061 --- [ main] c.e.c.CommandlinerunnerApplication : Started CommandlinerunnerApplication in 1.12 seconds (JVM running for 1.735)
CLR running!
real 0m1.784s
user 0m3.328s
sys 0m1.156s
GraalVM本地图像所需时间为0.100秒。
$ time ./clr
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot ::
Dec 04, 2019 12:57:58 AM org.springframework.boot.StartupInfoLogger logStarting
INFO: Starting CommandlinerunnerApplication on ST180329 with PID 1121 (/home/tkani/graalvm/spring-graal-native/spring-graal-native-samples/commandlinerunner/clr started by tkani in /home/tkani/graalvm/spring-graal-native/spring-graal-native-samples/commandlinerunner)
Dec 04, 2019 12:57:58 AM org.springframework.boot.SpringApplication logStartupProfileInfo
INFO: No active profile set, falling back to default profiles: default
Dec 04, 2019 12:57:58 AM org.springframework.boot.StartupInfoLogger logStarted
INFO: Started CommandlinerunnerApplication in 0.044 seconds (JVM running for 0.046)
CLR running!
real 0m0.100s
user 0m0.016s
sys 0m0.078s
GraalVM本地映像真是快得多,大约快17倍!
最终
听说GraalVM在讨论中经常会提到,它的启动速度很快,但在运行时比JIT慢的情况也是存在的。虽然我们可以通过实验性的项目(spring-graal-native)来进行速度比较,但这个速度非常有吸引力。一旦Spring Boot的GraalVM本地镜像支持正式发布,我一定想要尝试使用它。
明天的ZOZO Technologies #4 Advent Calendar 2019的第五天也是由@tkani发布的“使用Postman测试301重定向”的帖子。