一、概述
Spring Native提供了使用GraalVM 本机图像编译器将Spring应用程序编译为本机可执行文件的支持。与Java虚拟机相比,本机映像可以为许多类型的工作负载提供更便宜,更可持续的托管。这些包括微服务,功能工作负载,非常适合容器和Kubernetes。使用本机映像具有关键优势,例如即时启动,即时峰值性能和减少的内存消耗。
二、安装Graalvm
-
安装包下载
1)基础包下载
我们使用的安装包是21.0.0.2 Java8的windows版本
安装包下载:github.com/graalvm/gra…
2)native-image包下载
native-image用于打本地镜像
-
安装Graalvm
1)解压安装包
将下载好的安装压缩包解压到文件系统,比如:c:/graavm
2)环境变量配置
配置JAVA_HOME和PATH环境变量。在Windows 7、8和10中,通过命令行设置环境变量的工作方式相同。
将PATH环境变量指向GraalVM的bin目录:
管理员模式下在cmd命令行窗口执行如下命令:
setx /M PATH "C:\graalvm\graalvm-ce-java8-21.0.0.2\bin;%PATH%"
设置JAVA_HOME环境变量以解析到GraalVM安装目录:
管理员模式下在cmd命令行窗口执行如下命令:
setx /M JAVA_HOME "C:\graalvm\graalvm-ce-java8-21.0.0.2"
请注意/M,等同于的标志-m需要提升的用户特权。
-
安装native-image
1)本地安装native-image
gu -L install native-image-installable-svm-java8-windows-amd64-21.0.0.2.jar
2)查看已安装的组件
gu list
-
安装native-image打包依赖环境
1)windows编译依赖环境安装
- 点击vs_buildtools.exe安装C++编译环境,需要联网下载,大概1.6g大小,离线安装参考Windows C++ build Tools离线安装
-
版本测试
-
验证Java环境是否正常
-
输入java -version验证版本
java -version
openjdk version "1.8.0_282"
OpenJDK Runtime Environment (build 1.8.0_282-b07)
OpenJDK 64-Bit Server VM GraalVM CE 21.0.0.2 (build 25.282-b07-jvmci-21.0-b06, mixed mode)
-
验证native-image打包环境
- 创建测试代码:
public class Example { public static void main(String[] args) { String str = "Native Image is awesome"; String reversed = reverseString(str); System.out.println("The reversed string is: " + reversed); }
public static String reverseString(String str) { if (str.isEmpty()) return str; return reverseString(str.substring(1)) + str.charAt(0); }}
-
编译代码
-
打原生镜像包
使用如下命令大巴
native-image Example
打包完成后会成example.exe二进制文件
- 运行镜像包
直接在命令行运行example.exe,输出如下:
-
总结
1)整个环境搭建最麻烦的地方是windows的C++ 编译工具,文件不仅大,安装且特别慢
2)其他环境(mac、linux)的安装过程后续补充,TODO
3)相关安装包我会上传至百度网盘,方便大家下载,特别graalvm安装需要从github上下载,特别慢,需要科学上网才行,所以我会上传至百度网盘,网盘地址:
链接:https://pan.baidu.com/s/1F6F9sMOJnlOHmlHvqiTQ_A
提取码:7rc1
三、Spring Native示例
官方文档:Spring Native documentation
-
创建spring boot项目
创建一个spring boot项目,只包含web项目即可
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
完整的github项目地址:github.com/wenit/labs/…
目前Spring Native 最新版本为 0.9.1仅支持Spring Boot 2.4.4,所以我们创建Spring Boot项目的版本号也必须是这个版本。
pom.xml文件修改spring-boot-starter-parent的版本号为2.4.4
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.4.4</version>
<relativePath/>
</parent>
-
配置maven仓库
在pom文件中添加如下配置:
将构建配置为包括spring-native依赖项所需的存储库,如下所示:
<repositories>
<!-- ... -->
<repository>
<id>spring-release</id>
<name>Spring release</name>
<url>https://repo.spring.io/release</url>
</repository>
</repositories>
Spring AOT插件还需要专用的插件存储库:
<pluginRepositories>
<!-- ... -->
<pluginRepository>
<id>spring-release</id>
<name>Spring release</name>
<url>https://repo.spring.io/release</url>
</pluginRepository>
</pluginRepositories>
-
添加Spring Native依赖项
org.springframework.experimental spring-native 0.9.1 -
添加Spring AOT插件
Spring AOT插件执行提前转换,以改善本机图像兼容性和覆盖范围。
<build>
<plugins>
<!-- ... -->
<plugin>
<groupId>org.springframework.experimental</groupId>
<artifactId>spring-aot-maven-plugin</artifactId>
<version>0.9.1</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>
-
启用native-image支持
GraalVM提供了一个Maven插件来从您的Maven构建中调用native-image编译器。以下示例添加了一个native-image在package阶段中触发插件的配置文件:
注意修改mainClass为实际main程序类名称
<profiles>
<profile>
<id>native-image</id>
<build>
<plugins>
<plugin>
<groupId>org.graalvm.nativeimage</groupId>
<artifactId>native-image-maven-plugin</artifactId>
<version>21.0.0</version>
<configuration>
<!-- The native image build needs to know the entry point to your application -->
<mainClass>com.example.restservice.RestServiceApplication</mainClass>
<imageName>${project.artifactId}</imageName>
</configuration>
<executions>
<execution>
<goals>
<goal>native-image</goal>
</goals>
<phase>package</phase>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
在默认的Spring Boot设置中,它们spring-boot-maven-plugin也将在此package阶段运行,并用重新打包的可执行jar替换常规jar。为了避免两个插件之间发生冲突,请确保exec为可执行jar指定一个如下所示的分类器:
<plugins>
<!-- ... -->
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<classifier>exec</classifier>
</configuration>
</plugin>
</plugins>
-
生成本机应用程序
前提条件,需要升级maven版本号至3.3.9,并配置好maven环境变量,我使用的maven最新版本为 3.6.3
然后进入x64 Native Tools Command Prompt命令行环境
点击左下角的开始菜单,点击x64 Native Tools Command Prompt进入命令行环境
在此命令行环境中才能打包
mvn -Pnative-image package -Dmaven.test.skip=true
占用的大量内存,就一个最简单的Spring Boot项目,打包为native包竟然要5.91G内存😅
-
运行本机应用程序
打包完成我们进入项目的target目录,我们可以看到一个二进制文件:
然后我们运行这个文件,双击或者命令行运行都可以,双击二进制文件打开如下窗口:
-
测试本机应用程序
服务启动完成后,默认会的web端口是8080,我们在浏览器里访问如下接口,测试下交易:
测试地址:http://localhost:8080/hello
服务器会返回如下报文:
{
count: 1,
time: 1616670127994
}
出现如下界面说明服务测试成功
四、常见问题
-
Error: loading: ... graalvm-ce-java8-21.0.0.2jre\bin\server\jvm.dll
在win10 沙箱环境遇到此问题,切换到graalvm-ce-java11-21.0.0.2无此问题
-
Default native-compiler executable 'cl.exe' not found via environment variable PATH
解决方法:
添加环境PATH环境变量:
C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\VC\Tools\MSVC\14.28.29910\bin\HostX64\x64
-
fatal error C1034: stdio.h
解决方法:
1)需要安装
2)进入x64 Native Tools Command Prompt命令行环境
点击左下角的开始菜单,点击x64 Native Tools Command Prompt进入命令行环境
3)进入x64 Native Tools Command Prompt命令行环境后,再执行native-image,进行打包
-
打包springboot native image报maven版本过低错误
Failed to execute goal org.graalvm.nativeimage:native-image-maven-plugin:21.0.0:native-image (default) on project spring-native-demo: The plugin org.graalvm.nativeimage:native-image-maven-plugin:21.0.0 requires Maven version 3.3.9
解决方法:
升级maven版本
-
未设置main.class导致打包异常
Error: Main entry point class 'com.example.restservice.RestServiceApplication' not found.
解决方法:
在pom.xml的properties中添加main.class配置项目,并指定类名称
<properties>
<java.version>1.8</java.version>
<main.class>com.example.demo.SpringNativeDemoApplication</main.class>
</properties>
并在插件中引用此配置项
<plugin>
<groupId>org.graalvm.nativeimage</groupId>
<artifactId>native-image-maven-plugin</artifactId>
<version>21.0.0</version>
<configuration>
<!-- The native image build needs to know the entry point to your application -->
<mainClass>${main.class}</mainClass>
</configuration>
<executions>
<execution>
<goals>
<goal>native-image</goal>
</goals>
<phase>package</phase>
</execution>
</executions>
</plugin>
-
Windows C++ build Tools离线安装
1)离线下载安装包
使用vs_BuildTools.exe 在cmd命令行使用如下命令下载安装包,安装存储在当前目录下的buildTools-C++文件夹下,总大小估计1.6左右
vs_BuildTools.exe --layout buildTools-C++ --add Microsoft.VisualStudio.Workload.VCTools --includeRecommended --lang zh-CN
这个包比较大下载可能比较慢,我提供的百度网盘地址如下:
链接:https://pan.baidu.com/s/1F6F9sMOJnlOHmlHvqiTQ_A
提取码:7rc1
2)运行vs_setup.exe
下载完毕后,进入buildTools-C++目录,点击vs_setup.exe文件进行安装