GraalVM + Native-Image + Springboot3(实战)

一、首先,我们肯定需要准备一个Springboot项目

1、新建一个项目,JDK使用graalvm-jdk17:

1689238108822212.png

Springboot版本我选择3.1.1,以一个web项目为例:1689238233188756.png

自动生成核心的pom.xml文件:

<!-- 重点就是这个插件 -->
<build>
    <plugins>
        <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>

2、编写一个简单的Controller:

package com.jiguiquan.www.controller;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @Author jiguiquan
 * @Email jiguiquan@haier.com
 * @Data 2023-07-13 16:52
 */
@RestController
public class DemoController {

    @GetMapping("/")
    public String demo(){
        return "Hello Springboot3 AOT";
    }
}

3、常规运行访问该demo接口:

1689238545929721.png

项目无问题,可用于测试!


二、使用native-image命令编译Springboot项目(Windows)

核心命令:

1、先对原项目进行一次package打包:mvn clean package -DskipTests
2、运行aot提前处理命令:mvn spring-boot:process-aot
3、运行native打包:mvn -Pnative native:build
当然,也可以在Idea的界面上进行操作!

1、但是如果在Windows环境下,直接运行 native:build 命令,会报如下的错误:

Execution of C:\Program Files\Java\graalvm22-java17\bin\native-image.cmd @target\tmp\native-image-13566609948477534673.args returned non-zero result

这个错误解决起来,还挺麻烦的!需要配置一些列的环境变量!

需要修改3个环境变量:Path、INCLUDE、lib

我们需要知道自己的Visual Studio和Windows Kits包的安装位置,我的:

  • Visual Studio安装目录:C:\Program Files\Microsoft Visual Studio\2022\Community

  • 其中MSVC的include目录位置:C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.35.32215\include

  • 其中MSVC的lib目录位置:C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.35.32215\lib\x64

  • Windows工具包的include目录位置:C:\Program Files (x86)\Windows Kits\10\Include\10.0.22000.0\

  • Windows工具包的lib目录位置:C:\Program Files (x86)\Windows Kits\10\Lib\10.0.22000.0\

  • 配置第1个环境变量,在Path中添加:

C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.33.31629\bin\Hostx64\x64

1689242677999870.png

  • 配置第2个环境变量,新增INCLUDE环境变量:

C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.35.32215\include;C:\Program Files (x86)\Windows Kits\10\Include\10.0.22000.0\shared;C:\Program Files (x86)\Windows Kits\10\Include\10.0.22000.0\ucrt;C:\Program Files (x86)\Windows Kits\10\Include\10.0.22000.0\um;C:\Program Files (x86)\Windows Kits\10\Include\10.0.22000.0\winrt;

1689242721790191.png

  • 配置第3个环境变量,新增lib环境变量:

C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.35.32215\lib\x64;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.22000.0\um\x64;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.22000.0\ucrt\x64;

1689242019176787.png

2、上面的环境变量正确配置完成后,我们就可以执行最初的命令了:

为了保险起见,我们将在本地native工具中执行native编译操作:

#0 进入项目位置:
C:\Program Files\Microsoft Visual Studio\2022\Community>e:
E:\>cd E:\Study-Code\jdk17Sb3\graalvmsb3

#1 执行传统的mvn package命令:
E:\Study-Code\jdk17Sb3\graalvmsb3>mvn clean package -DskipTests

#2 执行springboot项目aot预处理操作:
E:\Study-Code\jdk17Sb3\graalvmsb3>mvn spring-boot:process-aot

#3 使用native-image将项目jar包打成可执行文件:
E:\Study-Code\jdk17Sb3\graalvmsb3>mvn -Pnative native:build
......
Produced artifacts:
 E:\Study-Code\jdk17Sb3\graalvmsb3\target\graalvmsb3.build_artifacts.txt (txt)
 E:\Study-Code\jdk17Sb3\graalvmsb3\target\graalvmsb3.exe (executable)
========================================================================================================================
Finished generating 'graalvmsb3' in 59.7s.
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  01:04 min
[INFO] Finished at: 2023-07-13T18:17:04+08:00
[INFO] ------------------------------------------------------------------------

最终生成了一个可执行文件 graalvnsb3.exe 文件!

3、我们直接双击运行 graalvnsb3.exe 文件,验证打包是否成功:

1689243661764149.png

整个项目在0.1秒内完成了启动,这也就验证了,为什么说AOT打成可执行文件后,运行速度非常快!


三、使用native-image命令编译Springboot项目(Linux)

关于Linux上 GraalVM + native-image 环境安装,查看我的另一篇文章:AOT技术与GraalVM的安装与简单使用

1、首先将我么的项目拷贝到Linux服务器上:

[root@jiguiquan graalvmsb3]# pwd
/code/graalvmsb3
[root@jiguiquan graalvmsb3]# ls
pom.xml  src

2、执行传统的mvn package命令:

[root@jiguiquan graalvmsb3]# mvn clean package -DskipTests

# 观察下执行后target目录
[root@jiguiquan graalvmsb3]# ls target/
classes  generated-sources  generated-test-sources  graalvmsb3-0.0.1-SNAPSHOT.jar  graalvmsb3-0.0.1-SNAPSHOT.jar.original  maven-archiver  maven-status  test-classes

3、执行springboot项目aot预处理操作:

[root@jiguiquan graalvmsb3]# mvn spring-boot:process-aot

# 在观察下target目录,可以看到,多个个apring-aot/目录
[root@jiguiquan graalvmsb3]# ls target/
classes  generated-sources  generated-test-sources  graalvmsb3-0.0.1-SNAPSHOT.jar  graalvmsb3-0.0.1-SNAPSHOT.jar.original  maven-archiver  maven-status  spring-aot  test-classes

4、使用native-image将项目jar包打成可执行文件:

[root@jiguiquan graalvmsb3]# mvn -Pnative native:build
......
Produced artifacts:
 /code/graalvmsb3/target/graalvmsb3 (executable)
 /code/graalvmsb3/target/graalvmsb3.build_artifacts.txt (txt)
========================================================================================================================
Finished generating 'graalvmsb3' in 2m 43s.
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  02:45 min
[INFO] Finished at: 2023-07-14T09:56:56+08:00
[INFO] ------------------------------------------------------------------------

# 再次观察target目录,可以看到,又多了一些文件,主要是:graalvmsb3 可执行文件
[root@jiguiquan graalvmsb3]# ls target/
classes            generated-test-sources         graalvmsb3                     graalvmsb3-0.0.1-SNAPSHOT.jar.original  maven-archiver  spring-aot
generated-sources  graalvm-reachability-metadata  graalvmsb3-0.0.1-SNAPSHOT.jar  graalvmsb3.build_artifacts.txt          maven-status    test-classes

5、执行生成的 graalvmsb3 二进制文件,检查是否正常:

[root@jiguiquan graalvmsb3]# target/graalvmsb3 

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::                (v3.1.1)

2023-07-14T10:00:15.742+08:00  INFO 2661 --- [           main] c.jiguiquan.www.Graalvmsb3Application    : Starting AOT-processed Graalvmsb3Application using Java 17.0.7 with PID 2661 (/code/graalvmsb3/target/graalvmsb3 started by root in /code/graalvmsb3)
2023-07-14T10:00:15.742+08:00  INFO 2661 --- [           main] c.jiguiquan.www.Graalvmsb3Application    : No active profile set, falling back to 1 default profile: "default"
2023-07-14T10:00:15.761+08:00  INFO 2661 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port(s): 9090 (http)
2023-07-14T10:00:15.762+08:00  INFO 2661 --- [           main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
2023-07-14T10:00:15.762+08:00  INFO 2661 --- [           main] o.apache.catalina.core.StandardEngine    : Starting Servlet engine: [Apache Tomcat/10.1.10]
2023-07-14T10:00:15.771+08:00  INFO 2661 --- [           main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2023-07-14T10:00:15.771+08:00  INFO 2661 --- [           main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 29 ms
2023-07-14T10:00:15.806+08:00  INFO 2661 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 9090 (http) with context path ''
2023-07-14T10:00:15.807+08:00  INFO 2661 --- [           main] c.jiguiquan.www.Graalvmsb3Application    : Started Graalvmsb3Application in 0.078 seconds (process running for 0.084)

可以看到,启动速度贼快,0.1s内就完成了项目启动!

1689300272491891.png

对外提供服务也正常!

Linux系统的打包工作比Windows系统顺利很多,所以我们以后工作中,主要的打包场景还是在Liunx服务器上!

jiguiquan@163.com

文章作者信息...

2 Comments

  • 打成可执行文件后,如何通过配置更改http.port,比如上面给的配置是端口是9090的,打成可执行文件之后,如何通过配置来更改这个配置为8080?

    • @andy 通过环境变量的方式,云原生时代,springboot的常改的配置,更推荐使用k8s的环境变量进行配置。

留下你的评论

*评论支持代码高亮<pre class="prettyprint linenums">代码</pre>

相关推荐