本机构建 native-image
如果你本地安装了 Graal VM 的话,可以在项目目录下直接执行:
mvn clean package -Pnative
构建的时间比较长,构建完成后就会在 ./target
目录下生成一个二进制执行文件,一般名字是 quarkus-demo-1.0-runner
,直接执行这个二进制文件就可以运行项目了。
➜ target: ./quarkus-demo-1.0-runner __ ____ __ _____ ___ __ ____ ______ --/ __ \/ / / / _ | / _ \/ //_/ / / / __/ -/ /_/ / /_/ / __ |/ , _/ ,< / /_/ /\ \ --\___\_\____/_/ |_/_/|_/_/|_|\____/___/ 2021-07-09 16:54:10,812 INFO [io.quarkus] (main) quarkus-demo 1.0 native (powered by Quarkus 2.0.1.Final) started in 0.121s. Listening on: http://0.0.0.0:8080 2021-07-09 16:54:11,041 INFO [io.quarkus] (main) Profile prod activated. 2021-07-09 16:54:11,041 INFO [io.quarkus] (main) Installed features: [cdi, resteasy, smallrye-context-propagation] ^C2021-07-09 16:55:12,904 INFO [io.quarkus] (Shutdown thread) quarkus-demo stopped in 0.008s
容器构建 native-image
如果你本地没有安装 Graal VM 的话,Quarkus 官方还提供了一个构建的基础镜像:quay.io/quarkus/ubi-quarkus-native-image
,我们可以直接执行以下命令进行构建:
mvn clean package -Pnative -Dquarkus.native.container-build=true
容器构建遇到的问题
1. 构建时内存不足
在使用容器构建 native-image 的时候,可以会报如下错误:
[ERROR] Failed to execute goal io.quarkus:quarkus-maven-plugin:2.0.1.Final:build (default) on project quarkus-demo: Failed to build quarkus application: io.quarkus.builder.BuildException: Build failure: Build failed due to errors [ERROR] [error]: Build step io.quarkus.deployment.pkg.steps.NativeImageBuildStep#build threw an exception: java.lang.RuntimeException: Failed to build native image [ERROR] at io.quarkus.deployment.pkg.steps.NativeImageBuildStep.build(NativeImageBuildStep.java:223) [ERROR] at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) [ERROR] at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) [ERROR] at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) [ERROR] at java.base/java.lang.reflect.Method.invoke(Method.java:566) [ERROR] at io.quarkus.deployment.ExtensionLoader$2.execute(ExtensionLoader.java:820) [ERROR] at io.quarkus.builder.BuildContext.run(BuildContext.java:277) [ERROR] at org.jboss.threads.ContextHandler$1.runWith(ContextHandler.java:18) [ERROR] at org.jboss.threads.EnhancedQueueExecutor$Task.run(EnhancedQueueExecutor.java:2442) [ERROR] at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1476) [ERROR] at java.base/java.lang.Thread.run(Thread.java:829) [ERROR] at org.jboss.threads.JBossThread.run(JBossThread.java:501) [ERROR] Caused by: java.lang.RuntimeException: Image generation failed. Exit code was 137 which indicates an out of memory error. Consider increasing the Xmx value for native image generation by setting the "quarkus.native.native-image-xmx" property [ERROR] at io.quarkus.deployment.pkg.steps.NativeImageBuildStep.imageGenerationFailed(NativeImageBuildStep.java:360) [ERROR] at io.quarkus.deployment.pkg.steps.NativeImageBuildStep.build(NativeImageBuildStep.java:200) [ERROR] ... 11 more [ERROR] -> [Help 1] [ERROR] [ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch. [ERROR] Re-run Maven using the -X switch to enable full debug logging. [ERROR] [ERROR] For more information about the errors and possible solutions, please read the following articles: [ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/MojoExecutionException
错误提示时内存不足,可以尝试设置 quarkus.native.native-image-xmx
参数,但是设置了这个参数还是报这个错。在查阅资料后,在一个 stackoverflow 的回答中看到了这样一句话:
Pay attention it has to be less than the memory you set in your docker daemon.
他说必须小于您在 docker 守护进程中设置的内存。
然后我查看 docker 的官方文档时发现,在 Mac 和 Windows 中默认的内存是 2GB。
所以只要调高这个值就可以了,推荐是 8GB,各系统设置方法:
Mac:docs.docker.com/docker-for-…
Windows:docs.docker.com/docker-for-…
2. 容器构建后的二进制文件无法运行
容器构建 native-image 完成后生成的二进制文件不能执行,提示 zsh: exec format error: ./quarkus-demo-1.0-runner
这是因为我本机是 Mac 系统,但是 Quarkus 提供的构建镜像是 Linux 系统,但是 Graal VM 目前好像并不支持交叉编译,所以在 Linux 系统里构建的二进制文件只能在 Linux 系统里执行。
所以我们可以直接用容器来运行这个构建好的二进制文件。