qinfengge

qinfengge

醉后不知天在水,满船清梦压星河
github

spring boot 3 + graalVM native 初体验

spring boot 3 已经出来一段时间了,官方也把 GraalVM native 作为 sp3 的一个重大的功能。

那什么是 GraalVM 呢?#

从名字就可以看出来 GraalVM 是一个虚拟机,它的主要目标就是提升 java 应用程序的性能,并且消耗更少的资源。

它在 java HotSpot JVM 的基础上添加了 JIT 编译器和 AOT 来实现将应用编译成为本地可执行文件。除了 java 之外,GraalVM 还支持 JavaScript、Ruby、Python 等多种编程语言。

通俗点讲,GraalVM 能够让 Java 或其它语言用其解释器编译为二进制程序。用 spring boot 3 框架编写的 Java 程序被转换后,启动速度更快,内存占用更小,到达最佳性能用时更短。

为什么需要 GraalVM?#

为什么 Java 这么重视 GraalVM 呢?

众所周知,Java 作为一门语言,渐渐跟不上新兴的技术与潮流。虽然 JDK 一直在更新,但还是受限于历史包袱的原因,船大难掉头。

这其中云原生,serverless,容器化这些新潮玩意就不讲武德猛踹 Java 那条坏腿。虽然还没到踹到半死不活的地步,但这是未来大势,不可阻挡。

关于 serverless 的思考#

对于 serverless (无服务器计算) 的 Providers (云服务器商) 而言,更小的内存占用,更快的启动速度无疑是降低成本的必然选择。

对于 Consumer (消费者 - 企业) 而言,省去了购买服务器及运维的钱,又支持按量计费,无疑非常有吸引力。

另一方面,AI 大模型对行业重新洗牌,但有能力训练、部署、迭代的只有大公司,而又可以提供大模型能力的只有云服务器商。那 serverless 就几乎只能成为中小公司对接 AI 的最佳选择。

安装 GraalVM#

官方网站下载并解压,完成后需配置环境变量

可以使用官方的配置方式

#注意修改下面的地址为你本地解压的地址
setx /M PATH "C:\Program Files\Java\graalvm-ce-java11-20.3.0\bin;%PATH%"
setx /M JAVA_HOME "C:\Program Files\Java\graalvm-ce-java11-20.3.0"

也可以直接配置环境变量

win + i 进入设置 --- 高级系统设置 --- 环境变量,增加如下的配置

GRAALVM_HOME :解压的路径
JAVA_HOME :解压的路径

image

然后在path里面配置

%GRAALVM_HOME%\bin
%JAVA_HOME%\bin

使用 cmd 的 java -version命令查看版本,如果有 GraalVM 字样表示成功

image

安装编译环境#

要将 Java 通过 GraalVM 编译成二进制,需要安装 C++ 环境

以下是通过Visual Studio安装相关环境的方法,你也可以查看官方教程

如果你是 Windows 11,不要使用官方教程里面的 Visual Studio 2019,而应该使用最新版

安装下面的组件

image

创建 spring boot 3 项目#

使用 idea 创建

image

JDK 要选择 GraalVM 的,Java 版本要选择 17 及以上的

image

选择 spring boot 3.0 以上版本,添加 GraalVM Native Support 和 Web 依赖

创建完成后 maven 文件中应有如下插件

image

完成后新建一个 controller 编写一个简单的接口

@RestController
@RequestMapping("user")
public class UserController {

    @GetMapping("test")
    public String test(){
        return "hello world";
    }

编译及构建#

代码写完了,我们就要编译了

打开 Visual Studio Build Tools x64 Native Tools Command Prompt for VS 2022

image

x64、x86 都是可以的,然后进入项目目录

使用 mvn -PnativeTest test进行编译测试

没有错误后使用 mvn native:build 进行构建,完成后会在项目目录生成一个 exe 文件

image

image

可以看到,构建后的文件还是很大的,这是因为在构建过程中打包了一些依赖

image

其中大约 50M 是代码的体积,这一部分还包含了一个 java.base

30M 是镜像的堆体积,剩下的是其它数据

启动 exe 文件,发现速度可以说是光速了

image

现有不足#

GraalVM 可以说是一个非常有意思的东西,它是 Java 对云原生的一次勇敢尝试,它解决了 Java 的重大弊病,但同时也带了致命的问题。

Java 中的动态调用支持引入各种依赖,并在调用时进行指向,而 GraalVM Native 使用的 AOP (提前编译) 是基于静态代码可达分析。通俗点讲就是 Java 编译时不知道你有什么用,但在调用时就可以找到了,而 GraalVM 在编译时则一定要指定你是谁,你有什么用。

GraalVM 牺牲了编译耗时,优化了启动耗时。这当然是正确的,但它也无法动态调用了。

尽管其提供了使用反射解决的方法,但目前仍非常复杂

我尝试引入 mybatis 的依赖,但并未使用,测试编译就并未通过。

GraalVm Native Image 官方文档

GraalVM 编译 spring3.0 (云原生时代)

在 spring boot3 中使用 native image

Using GraalVM and Native Image on Windows 10

GraalVM 安装及编译项目为可执行 exe 文件

[cl.exe missing when building native app using GraalVM]

Maven GraalVm native tests (mvn -PnativeTest test)

加载中...
此文章数据所有权由区块链加密技术和智能合约保障仅归创作者所有。