1. GraalVM诞生的背景
1.1. Java在微服务/云原生时代的困境及解决方案
事实
Java总体上是面向大规模、长时间的服务端应用而设计的。
即时编译器(JIT)、性能优化、垃圾回收等有代表性的特征需要一段时间来达到最佳性能。
矛盾
微服务时代对启动速度达到最高性能的时间提出了新的要求!
在微服务的背景下,提倡服务围绕业务能力构建,不再追求实现上的严谨一致。
单个微服务就不再需要再面对数十、数百GB乃至TB的内存。
有了高可用的服务集群,也无须追求单个服务要7×24小时不可间断地运行,它们随时可以中断和更新。
所以微服务对应用的容器化(Docker)亲和度(包容量、内存消耗等)、启动速度、达到最高性能的时间等方面提出了新的要求,这些恰恰是Java的弱项。
比如:现在启动一个微服务项目(Docker运行6个子服务),动不动就1分钟,如下图:
问题根源
Java离不开虚拟机。
所以Java应用启动的时候,必须要启动虚拟机,进行类加载,无论是启动时间,还是占用空间都不是最优解。
解决方案
革命派
直接革掉Java和Java生态的性命,创造新世界,譬如Golang。
保守派
保留原有主流Java生态和技术资产,朝着微服务、云原生环境靠拢与适应(GraaIVM)。
2. GraalVM入门
GraalVM 是一个高性能 JDK 发行版,旨在加速用Java和其它JVM语言编写的应用程序的执行(JVM不只支持Java语言),并支持 JavaScript、Ruby、Python 和许多其他流行语言(翻译自官网 https://www.graalvm.org/)。
GraalVM底层也是HosSpot,只是做了二次开发,打包成JDK。GraalVM能让支持的语言使用HotSpot虚拟机。
GraalVM可以代替对应的JDK版本使用。
GraalVM想成为一统天下的“最终”虚拟机!而GraalVM要做到原因也很简单:
大部分脚本语言或者有动态特效的语言都需要一个语言虚拟机运行,比如CPython,Lua,Erlang,Java,Ruby,R,JS,PHP,Perl,APL等等,但是这些语言的虚拟机水平很烂,比如CPython的VM就不忍直视,而HotSpotVM是虚拟机的大神级别,如果能用上HotSpot,能用上顶级的即时编译器(JIT)、性能优化、垃圾回收等技术,岂不爽歪歪!
3. GraalVM特征
1. GraalVM是一款高性能的可嵌入式多语言虚拟机,它能运行不同的编程语言
能运行基于JVM的语言,比如Java, Scala, Kotlin和Groovy。
能运行解释型语言,比如JavaScript, Ruby, R和Python。
能运行,能配合LLVM运行的原生语言,比如C, C++, Rust和Swift。
2. GraalVM的设计目标是可以在不同的环境中运行程序在JVM中。
将代码编译成独立的本地镜像(不需要JVM),比如将Java代码编译成本地镜像就可以直接运行,不需要安装JDK环境。(符合云原生的要求不需要在环境里头再安装JDK)
将Java及本地代码模块集成为更大型的应用。
4. 安装配置GraalVM
下载压缩包
GraalVM分成了社区版与企业版,企业版肯定比社区版好,企业版可能涉及到收费问题。
这边因为演示使用社区版就够了,按JDK版本下载GraalVM对应的压缩包,请下载Java 17对应的版本,不然后面实战演示SpringBoot3(需要JDK17)可能会有问题。
下载地址 https://github.com/graalvm/graalvm-ce-builds/releases
下载完后,解压。
配置环境变量
类似这样
新开一个cmd测试,不同版本显示不一样。
安装native-image
cmd下运行gu list,查看有没安装native-image。
1. 在线安装
执行gu install native-image 命令安装即可。
2. 离线安装
以 GraalVM for JDK 17 Community 17.0.8 对应的23.0.1 版本为例, 地址:
下载地址:https://github.com/graalvm/graalvm-ce-builds/releases/tag/graal-23.0.1。
找到 native-image-installable-svm-java17-windows-amd64-23.0.1.jar 下载。
打开cmd, 进入 native-image-installable-svm-java17-windows-amd64-23.0.1.jar 下载的文件夹。
执行:gu install -L native-image-installable-svm-java17-windows-amd64-23.0.1.jar 安装即可。
验证运行gu list查看是否安装成功。
注意
1. 如graalvm 和native-image 版本不一致,会出现如下图的错误,找到对应的版本,重新安装即可;
安装Visual Studio Build Tools
因为在Windows上 使用要使用GraalVM的native-image打包需要c++环境,而VisualStudio 可以提供c++开发环境,所以我们要先下载安装好VisualStudio。
打开 visualstudio.microsoft.com这个网站 ,下载Visual Studio Installer。
选择C++桌面开发和Windows 11 SDK,然后进行下载和安装,安装后重启操作系统。
要使用GraalVM的native-image将代码编译成本地文件,不能使用普通的windows自带的命令行窗口。得使用VS提供的 x64 Native Tools Command Prompt for VS版本号。
如下
如果没有可以执行前面Visual Studio Build Tools安装目录文件夹下的Microsoft Visual Studio\版本号\BuildTools\VC\Auxiliary\Build\vcvars64.bat
**脚本来安装。
安装完之后可以运行x64 Native Tools Command Prompt for VS 版本号 ,去使用native-image命令去进行编译代码生成本地文件了。
如果后续在编译过程中编译失败了,出现以下错误:
那么可以执行cl.exe来进行编译,cl.exe如果是中文,那就得修改为英文。
可以通过再次启用Visual Studio Installer来修改你的安装配置,比如:
可能一开始只选择了中文,手动选择英文,去掉中文,然后安装(修改)即可。
再次检查,这样就可以正常的编译了。
5. Graal Compiler(了解就好)
Graal Compiler是GraalVM与HotSpotVM(从JDK10起)共同拥有的服务端即时编译器,是C2编译器的替代者。
Graal VM结构图如下
Graal Java–就是Graal编译器。
JVMCI—针对JVM编译的接口,因为Graal编译器是java写的,通过Compiler Interface调用JVM很麻烦就使用这个替代。
即时编译器(JIT编译器)是 Java 虚拟机中相对独立的模块,它主要负责接收 Java 字节码,并生成可以直接运行的二进制码。传统情况下(JDK8),即时编译器是与 Java 虚拟机紧耦合的。也就是说,对即时编译器的更改需要重新编译整个 Java 虚拟机。这对于开发相对活跃的 Graal 来说显然是不可接受的。
为了让 Java 虚拟机与 Graal编译器解耦合,引入了Java 虚拟机编译器接口(JVM Compiler Interface,JVMCI),因为Graal编译器是java编写的,将即时编译器的功能抽象成一个 Java 层面的接口。这样一来,在 Graal 所依赖的 JVMCI 版本不变的情况下&#