GraalVM Native 尝试
GraalVM 是一个支持原生图像编译的 JDK,可以直接把 java 代码编译为可执行文件,不需要 jvm 就可以运行。而 Spring 刚好也支持了 GraalVM,现在来尝试一下。
在 MacOS 上安装 GraalVM
可查看官网的安装指南:
Installation on macOS Platforms
使用 Homebrew 安装 GraalVM
官网提供了二进制文件,为了方便可以直接使用 Homebrew 进行安装:
brew install graalvm-jdk
配置环境变量
- 将 GraalVM 的 bin 路径加入到
PATH
环境变量 - 配置
JAVA_HOME
环境变量指向 GraalVM 的安装目录
查看 jdk 安装路径
# 查看本机安装的所有 jdk
/usr/libexec/java_home -V
可以看到 GraalVM 的安装路径为
/Library/Java/JavaVirtualMachines/graalvm-21.jdk/Contents/Home
配置环境变量:
echo "export JAVA_HOME='/Library/Java/JavaVirtualMachines/graalvm-21.jdk/Contents/Home'" >> ~/.zshrc
echo "export PATH='$JAVA_HOME/bin:$PATH'" >> ~/.zshrc
source ~/.zshrc
删除隔离属性(MacOS Catalina及更高版本)
此时运行
java --version
会报错,因为 MacOS 的保护机制,需要删除隔离属性:
sudo xattr -r -d com.apple.quarantine /Library/Java/JavaVirtualMachines/graalvm-21.jdk
此时再运行 java --version
就可以看到具体版本了:
创建一个 Spring Boot 项目尝试 GraalVM
使用 https://start.spring.io 网站提供的 Spring 项目脚手架,或者直接使用 IDEA 提供的项目创建功能
核心依赖和插件大概是这些:
plugins {
id("org.springframework.boot") version "3.2.3"
id("io.spring.dependency-management") version "1.1.4"
id("org.graalvm.buildtools.native") version "0.9.28"
kotlin("jvm") version "1.9.22"
kotlin("plugin.spring") version "1.9.22"
}
dependencies {
implementation("org.springframework.boot:spring-boot-starter-webflux")
implementation("com.fasterxml.jackson.module:jackson-module-kotlin")
implementation("io.projectreactor.kotlin:reactor-kotlin-extensions")
implementation("org.jetbrains.kotlin:kotlin-reflect")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-reactor")
testImplementation("org.springframework.boot:spring-boot-starter-test")
testImplementation("io.projectreactor:reactor-test")
}
添加一点示例代码:
@RestController
class HelloController {
@GetMapping("/hello")
suspend fun hello() = "Hello GraalVM"
}
编译项目:
./gradlew nativeCompile
编译完成的结果如下,M1 Pro 芯片大概花了 2分26 秒编译完成,感觉速度还可以🥳,编译结果是在<project path>/build/native/nativeCompile/<project name>
下。
编译出来的可执行文件大小为 96.5 MB,感觉还是挺大的,不过毕竟引入了整个 Spring 的依赖和 kotlin 依赖。纯 java 可能会更小一些。
接下来就是重头戏,直接运行可执行文件:
启动速度相当快,一瞬间就起来了,访问下接口:
内存占用 53.6 MB,感觉还行 😋