Linux安装底层工具相关依赖
yum install -y gcc glibc-devel zlib-devel
安装GraalVM JDK
《GraalVM官网下载》
找到最近的GraalVM Community Edition X.X.X点击Assets(因为我的是SpringBoot3项目,起始JDK就要求17,所以我下载17)下载速度慢的话,可以使用第三方下载工具,如:迅雷等
选择如下2个内容下载
graalvm-ce-java17-linux-amd64-X.X.X.tar.gz
native-image-installable-svm-java17-linux-amd64-X.X.X.jar
配置JDK环境变量为GraalVM的环境变量,因为GraalVM就是JDK
如果之前已经有Java的环境变量,则要替换为GraalVM
把文件上传到/usr/local/java/目录下进行解压graalvm-ce-java17-linux-amd64-X.X.X.tar.gz(GraalVM JDK)
mkdir -p /usr/local/java
cd /usr/local/java
tar -zxvf graalvm-ce-java17-linux-amd64-22.3.1.tar.gz
配置环境变量
vim /etc/profile
找到export PATH USER LOGNAME MAIL HOSTNAME HISTSIZE HISTCONTROL,在下面写上:
#java
export JAVA_HOME=/usr/local/java/graalvm-ce-java17-22.3.1
export CLASSPATH=.:$JAVA_HOME/lib
export PATH=$PATH:$JAVA_HOME/bin:$JAVA_HOME/jre/bin
java17是没有jre/bin目录的,但是为了方便切换到8版本,还是保留吧。想切换到java只需要修改环境变量JAVA_HOME为你java8的安装目录即可。
:wq保存并退出,使环境变量生效
source /etc/profile && java -version
输出
openjdk version "17.0.6" 2023-01-17
OpenJDK Runtime Environment GraalVM CE 22.3.1 (build 17.0.6+10-jvmci-22.3-b13)
OpenJDK 64-Bit Server VM GraalVM CE 22.3.1 (build 17.0.6+10-jvmci-22.3-b13, mixed mode, sharing)
安装GraalVM Native-Image
把native-image-installable-svm-java17-linux-amd64-X.X.X.jar上传到/usr/local/java/目录下进行安装
gu install --file native-image-installable-svm-java17-linux-amd64-22.3.1.jar
输入native-image --help看看控制台是否输出相关帮助命令,如果输出,则安装成功。
native-image --help
SpringBoot3
新增spring boot3项目选择JDK为GraalVM JDK17
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.fu</groupId>
<artifactId>spring-boot3-aot-graalvm-native-demo</artifactId>
<version>1.0-SNAPSHOT</version>
<!-- 没有跟demo-maven作为父子项目,而是以SpringBoot作为父项目 -->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.0.5</version>
<relativePath/>
</parent>
<properties>
<java.version>17</java.version>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
</properties>
<dependencies>
<!-- web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<!-- AOT Graalvm native maven 插件 -->
<plugin>
<groupId>org.graalvm.buildtools</groupId>
<artifactId>native-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
建个HelloController.java和SpringBootApplication启动类
@RestController
public class HelloController {
@GetMapping("hello")
public String hello() {
return "Hello World.";
}
}
把SpringBoot3打成jar包上传到linux服务器
native-image -jar springboot3-native-demo.jar
运行过程当中可能会产生一些警告或错误,但是程序是可以正常运行的,因为打成二进制(汇编)需要的是确定的、不可变的类型,而反射、泛型等是动态的类型,如果运行过程当中类型发生改变,则程序就会出错,因此会发出警告。
GraalVM Native Image: Generating 'springboot3-native-demo' (executable)...
========================================================================================================================
[1/7] Initializing... (4.1s @ 0.18GB)
Version info: 'GraalVM 22.3.1 Java 17 CE'
Java version info: '17.0.6+10-jvmci-22.3-b13'
C compiler: gcc (redhat, x86_64, 4.8.5)
Garbage collector: Serial GC
[2/7] Performing analysis... [******] (19.3s @ 0.61GB)
3,587 (76.86%) of 4,667 classes reachable
4,509 (52.77%) of 8,545 fields reachable
16,135 (45.95%) of 35,113 methods reachable
160 classes, 0 fields, and 539 methods registered for reflection
59 classes, 59 fields, and 52 methods registered for JNI access
4 native libraries: dl, pthread, rt, z
[3/7] Building universe... (2.3s @ 0.49GB)
Warning: Reflection method java.lang.Class.forName invoked at org.springframework.boot.loader.MainMethodRunner.run(MainMethodRunner.java:46)
Warning: Reflection method java.lang.Class.getDeclaredMethod invoked at org.springframework.boot.loader.MainMethodRunner.run(MainMethodRunner.java:47)
Warning: Reflection method java.lang.Class.getDeclaredConstructor invoked at org.springframework.boot.loader.jar.Handler.getFallbackHandler(Handler.java:200)
Warning: Aborting stand-alone image build due to reflection use without configuration.
Warning: Use -H:+ReportExceptionStackTraces to print stacktrace of underlying exception
------------------------------------------------------------------------------------------------------------------------
0.6s (2.4% of total time) in 23 GCs | Peak RSS: 1.07GB | CPU load: 3.41
========================================================================================================================
Failed generating 'springboot3-native-demo' after 25.8s.
Generating fallback image...
Warning: Image 'springboot3-native-demo' is a fallback image that requires a JDK for execution (use --no-fallback to suppress fallback image generatformation why a fallback image was necessary).
打包会生成2个文件,第一个就是二进制可执行文件,第二个是构建工件(可以删除),第三个是jar文件(不能删除)。
启动/data/graalvm/下的springboot3-native-demo二进制可执行文件
PS:因为我把jar包上传到了/data/graalvm/目录下
/data/graalvm/springboot3-native-demo
输出
[root@node1 graalvm]# ./spring-boot3-aot-graalvm-native-demo-1.0-SNAPSHOT
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v3.0.5)
2023-07-02T11:18:20.990-04:00 INFO 2500 --- [ main] c.f.s.SpringBoot3AotGraalvmNativeDemo : Starting SpringBoot3AotGraalvmNativeDemo v1.0-SNAPSHOT using Java 17.0.6 with PID 2500 (/data/graalvm/spring-boot3-aot-graalvm-native-demo-1.0-SNAPSHOT.jar started by root in /data/graalvm)
2023-07-02T11:18:20.993-04:00 INFO 2500 --- [ main] c.f.s.SpringBoot3AotGraalvmNativeDemo : No active profile set, falling back to 1 default profile: "default"
2023-07-02T11:18:21.869-04:00 INFO 2500 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8080 (http)
2023-07-02T11:18:21.879-04:00 INFO 2500 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
2023-07-02T11:18:21.879-04:00 INFO 2500 --- [ main] o.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/10.1.7]
2023-07-02T11:18:21.951-04:00 INFO 2500 --- [ main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2023-07-02T11:18:21.953-04:00 INFO 2500 --- [ main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 889 ms
2023-07-02T11:18:22.306-04:00 INFO 2500 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path ''
2023-07-02T11:18:22.320-04:00 INFO 2500 --- [ main] c.f.s.SpringBoot3AotGraalvmNativeDemo : Started SpringBoot3AotGraalvmNativeDemo in 1.803 seconds (process running for 2.287)
2023-07-02T11:18:43.548-04:00 INFO 2500 --- [nio-8080-exec-2] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring DispatcherServlet 'dispatcherServlet'
2023-07-02T11:18:43.549-04:00 INFO 2500 --- [nio-8080-exec-2] o.s.web.servlet.DispatcherServlet : Initializing Servlet 'dispatcherServlet'
2023-07-02T11:18:43.550-04:00 INFO 2500 --- [nio-8080-exec-2] o.s.web.servlet.DispatcherServlet : Completed initialization in 1 ms
访问linux服务器的ip:8080/hello成功输出Hello World.
后台启动命令
nohup /data/graalvm/springboot3-native-demo >/dev/null 2>&1 &
查看后台是否启动项目8080是项目的端口号
netstat -ntlp | grep 8080