feat: graalvm adoc

pull/3002/head
musi 2 years ago
parent 6a221cdd0e
commit 18ea8a32b7

@ -0,0 +1,141 @@
== GraalVM in Spring Cloud Alibaba
=== GraalVM介绍
Spring Boot 3.0本次带来最大的改动就是GraalVM原生镜像的支持也是官方文档中强调的他们花费时间精力比较多的部分。 GraalVM技术作为JRE的替代方案其通过预先编译Ahead Of TimeAOT等技术对Java应用进行预先编译让Spring在运行应用时掌握更多应用有关的信息让整个应用启动速度更快。另外通过编译工具在编译过程中通过消除一些不必要的内容可以让最终的应用更小占用内存更低。对于一些对启动速度要求非常高的场景比如Serverless、FaaS场景非常友好 提到GraalVM技术其最早来自于 Spring 团队于2019年发起的 Spring Native 项目。它作为一个实验性质的项目,在过去几年通过与 Spring Boot 3.0 和 Spring Framework 6.0 之前的项目进行整合使用,据 Josh Long 在最近的相关采访透露,该实验项目已经验证了 Spring Boot 2.x 和 Spring Framework 5.x 的各项功能。本次 Spring Boot 3.0 直接将其正式从 Spring Native 迁入到 Spring Boot 中来也预示着该项技术开始逐渐走向成熟Spring生态开始迈入 GraalVM 阶段!
*跟 JVM 编译部署方式相比GraalVM 具有以下特点:*
* 在应用构建阶段,从主入口点就开始进行应用程序的静态分析。
* 创建本机镜像时,通过代码分析,会将无法访问的代码删除,并且不会成为可执行文件的一部分,从而可在一定程度上压缩程序包大小。
* GraalVM 无法直接感知代码的动态元素因此对于存在反射、序列化和动态代理的应用程序需要提前提供相关hint配置文件帮助解析应用程序相关操作过程可参考官方文档。
* 应用程序类路径在构建时是固定的,不能更改。
* 没有惰性类加载,可执行文件中的所有内容都将在启动时加载到内存中。
* 支持的 Java 应用程序在某些方面存在一些限制,因此目前并不能保证之前的 Java 应用都可直接使用GraalVM技术进行应用构建有一定概率会存在不兼容的异常情况。
本次发布的 Spring Cloud Alibaba 2022.0.0.0 版本所包含的部分中间件客户端已完成了构建 GraalVM 原生应用的适配,以下是社区对目前所支持的服务注册与发现、分布式事务模块相关示例应用在升级为 Spring Boot 3.0 以后使用GraalVM构建原生应用镜像做的在启动速度和运行时占用内容相关的测试Sentinel和RocketMQ目前还在适配中以下测试过程在MacOS 11.42.6 GHz 6-Core Intel Core i7处理器16G内存环境下分别模拟5次取平均值测得
image::./pic/graalvm_performance.png[]
从上述对比可发现,最新支持 Spring Boot 3.0 基于 GraalVM 的 Spring Cloud Alibaba 应用会在启动速度、运行时内存占用和应用包大小方面得到大幅度降低例如其中服务注册消费应用启动速度提升了近10倍运行时内存占用比原来降低了近乎2/3效果非常明显。这给云原生时代托管在云上的应用带来了显著优势让其可以更快的进行弹性扩缩容以及降低企业整体用云成本
=== 使用GraalVM技术构建应用
==== 项目构建
本次适配 Spring Boot 3.0 的 Spring Cloud Alibaba 所支持的所有组件中Nacos 2.2.1-RC 已经支持 GraalVM 技术构建应用。接下来,将介绍一下相关组件使用 GraalVM 技术进行应用编译与运行测试
按照一般的 Spring Cloud Alibaba 应用构建方式进行项目构建即可,以下为相关必须添加的依赖内容:
[source]
----
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.0.0</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<dependencies>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-commons</artifactId>
</dependency>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>2022.0.0</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>2022.0.0.0-RC1</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
----
以上为本次通过 Spring Cloud Alibaba 使用 Nacos 进行服务注册所需要的必要依赖,其他依赖请根据自身需求进行调整,请注意,使用 GraalVM spring-boot-starter-parent 父模块是非常关键的,其声明一个 native profile其中包含了创建、运行 GraalVM 原生映像的必要信息。 构建 Spring Boot 原生镜像应用主要有两种方式: 1. 使用 Spring Boot 对 Cloud Native Buildpacks 的支持来生成包含本机可执行文件的轻量级容器。 2. 使用 GraalVM Native Build Tools 生成本机可执行文件。 由于第一种方式使用过程中对本地环境有一定的要求,如需使用可参考 https://docs.spring.io/spring-boot/docs/current/reference/html/native-image.html#native-image.introducing-graalvm-native-images[Spring Boot 3.0] 相关用户文档。本文接下来演示使用第二种方式进行 GraalVM 应用构建。
=== 环境准备:
要使用 Native Build Tools 构建原生镜像,需要在首先在机器上安装 GraalVM 发行版。 您可以在 Liberica Native Image Kit 页面上手动下载它,也可以使用像 SDKMAN!
这样的下载管理器。本文演示环境为MacOS如果是 Windows 可参考相应文档进行操作。执行以下命令安装 GraalVM 环境:
[source,shell]
----
sdk install java 22.3.r17-nik
sdk use java 22.3.r17-nik
----
通过检查 java -version 的输出来验证是否配置了正确的版本:
[source,shell]
----
$ java -version
openjdk version "17.0.5" 2022-10-18 LTS
OpenJDK Runtime Environment GraalVM 22.3.0 (build 17.0.5+8-LTS)
OpenJDK 64-Bit Server VM GraalVM 22.3.0 (build 17.0.5+8-LTS, mixed mode)
----
==== 生成hint文件:
通过以下命令生成应用中反射、序列化和动态代理所需的hint配置文件。
[source,shell]
----
mvn -Pnative spring-boot:run
----
之后我们的example应用会启动我们需要尽可能完整的测试一遍example的所有功能保证应用的大部分代码都被测试用例覆盖这样才能确保完整生成应用运行过程中的所有必须的动态属性。 运行完所有测试用例后,我们发现`resource/META-INF/native-image` 目录下会生成以下一些hint文件:
- resource-config.json应用中资源hint文件
- reflect-config.json应用中反射定义hint文件
- serialization-config.json应用中序列化内容hint文件
- proxy-config.json应用中Java代理相关内容hint文件
- jni-config.json应用中Java Native InterfaceJNI内容hint文件
==== 构建原生镜像
以上步骤一切准备就绪后,通过以下命令来构建原生镜像:
[source,shell]
----
mvn -Pnative native:compile
----
成功执行后,我们在``/target``目录可以看到我们生成的可执行文件。
=== 启动原生镜像
与普通可执行文件无异,通过``target/nacos-config-2.4.x-example``启动本example, 可以观察到类似如下的输出:
[source,shell]
----
2022-12-22T16:28:51.006+08:00 INFO 75439 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8888 (http) with context path ''
2022-12-22T16:28:51.008+08:00 INFO 75439 --- [ main] c.a.cloud.imports.examples.Application : Started Application in 0.653 seconds (process running for 0.662)
----
可以发现应用的启动速度大大加快。 再通过``vmmap pid | grep Physical``命令查看运行过程中的内存占用情况 通过原生镜像启动的应用内存占用情况如下
```
Physical footprint: 59.2M
Physical footprint (peak): 59.2M
```
通过普通的方式启动Java应用的内存占用情况如下
```
Physical footprint: 214.0M
Physical footprint (peak): 256.8M
```
可以看到通过原生镜像启动Java应用后内存占用大大减少。 <br> 应用启动后各项功能与通过jar启动无异。

Binary file not shown.

After

Width:  |  Height:  |  Size: 288 KiB

@ -0,0 +1,131 @@
== GraalVM in Spring Cloud Alibaba
=== Introduction to GraalVM
One of the biggest changes of Spring Boot 3.0 is the support for GraalVM native images, which the official takes a lot of time and effort. GraalVM technology, as an alternative to JRE, precompels Java applications through technologies such as Ahead Of Time (AOT), which enables Spring to grasp more information about applications when running applications and makes the whole application start faster. In addition, the final application is smaller and has a lower memory footprint by eliminating unnecessary content during the compilation process through the compilation tool. It is excellent for some scenarios that require very high startup speed, such as Serverless and FaaS scenarios. GraalVM technology comes from Spring Native project initiated by Spring team in 2019. It is an experimental project that has been used over the past few years through integration with projects prior to Spring Boot 3.0 and Spring Framework 6.0, according to Josh Long in a recent interview. This experimental project has verified the functions of Spring Boot 2.x and Spring Framework 5.x. This Spring Boot 3.0 directly moves it from Spring Native to Spring Boot, which also indicates that this technology begins to mature gradually and Spring ecology begins to enter the GraalVM stage!
*GraalVM has the following features compared to the JVM compilation deployment:*
* During the application construction phase, static analysis of the application begins at the main entry point.
* When the native image is created, code analysis removes the inaccessible code and does not become part of the executable file, thus reducing the package size to some extent.
* GraalVM cannot directly sense the dynamic elements of the code. Therefore, for applications with reflection, serialization, and dynamic proxies, hint configuration files need to be provided in advance to help resolve the application. Refer to the official documents for related operations.
* The application classpath is fixed at build time and cannot be changed.
* Without lazy class loading, everything in the executable will be loaded into memory at startup.
* The supported Java applications have some limitations in some aspects. Therefore, it is not guaranteed that all the previous Java applications can directly use GraalVM technology for application construction, and there is a certain probability of incompatible exceptions.
Part of the middleware clients included in Spring Cloud Alibaba 2022.0.0.0 version of this release have completed the adaptation of constructing GraalVM native applications. The following is a sample application related to service registration, discovery and distributed transaction module supported by the community. After upgrading to Spring Boot 3.0, GraalVM is used to build a native application image to test the startup speed and runtime usage. (Sentinel and RocketMQ are still being adapted. The following test process is simulated for 5 times respectively under the environment of MacOS 11.4, 2.6GHz 6-Core Intel Core i7 processor and 16G memory) :
image::./pic/graalvm_performance.png[]
From the above comparison, we can see that the latest Spring Cloud Alibaba application that supports Spring Boot 3.0 based on GraalVM will reduce application's startup time, runtime memory usage and application package size. For example, Among them, the startup speed of the service registration consumption application is increased by nearly 10 times, and the running memory usage is reduced by nearly 2/3 compared with the original, which has a very obvious effect. This gives the cloud native era, hosting in the cloud application has brought significant advantages, so that it can be faster elastic expansion and contraction capacity and reduce the overall cost of the enterprise cloud!
=== Build Application by GraalVM
==== Build the project
Among all the components supported by Spring Cloud Alibaba for Spring Boot 3.0 this time, Nacos 2.1.1-RC already supports GraalVM technology to build applications. Next, we'll look at the components that use GraalVM technology to compile and run the application
The project construction can be carried out according to the general Spring Cloud Alibaba application construction method. The following are the relevant dependencies that must be added:
[source]
----
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.0.0</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<dependencies>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-commons</artifactId>
</dependency>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>2022.0.0</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>2022.0.0.0-RC1</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
----
The above are necessary dependencies for registering Nacos through Spring Cloud Alibaba. Please adjust other dependencies according to your own needs. Please note that It is critical to use the GraalVM spring-boot-starter-parent parent module, which declares a native profile that contains the necessary information to create and run GraalVM native images. There are two ways to build a Spring Boot native image application: 1. Use Spring Boot's support for Cloud Native Buildpacks to generate lightweight containers containing native executables. 2. Use GraalVM Native Build Tools to generate a local executable file. As the first method has certain requirements on the local environment, If you need to use can refer to https://docs.spring.io/spring-boot/docs/current/reference/html/native-image.html#native-image.introducing-graalvm-native[Spring Boot 3.0] related user documents. The rest of this article demonstrates the second approach to GraalVM application building.
=== Preparation:
To Build a Native image using Native Build Tools, you need to firstly install the GraalVM distribution on your machine. You can download it manually on the Liberica Native Image Kit page, or you can use tools like SDKMAN!. Run the following command to install the GraalVM environment:
[source,shell]
----
sdk install java 22.3.r17-nik
sdk use java 22.3.r17-nik
----
Verify that the correct version is configured by checking the output of java -version:
[source,shell]
----
$ java -version
openjdk version "17.0.5" 2022-10-18 LTS
OpenJDK Runtime Environment GraalVM 22.3.0 (build 17.0.5+8-LTS)
OpenJDK 64-Bit Server VM GraalVM 22.3.0 (build 17.0.5+8-LTS, mixed mode)
----
=== Generate hint file:
Generate hint configuration files required for reflection, serialization, and dynamic proxies in your application by using the following command.
[source,shell]
----
mvn -Pnative spring-boot:run
----
After our example application is launched, we need to test all functions of example as completely as possible to ensure that most code of the application is covered by test cases, so as to ensure that all necessary dynamic properties during the application operation are generated completely.
After running all the test cases, we found the following hint files are generated in ``resource/META-INF/native image`` directory:
- resource-config.jsonResource hint file
- reflect-config.jsonReflection definition hint file
- serialization-config.jsonSerialization hint file
- proxy-config.jsonProxy hint file
- jni-config.jsonJNI hint file
=== Build native image
After all the above steps are in place, use the following command to build the native image:
```shell
mvn -Pnative native:compile
```
After that, we can see the executable we generated in the ``/target`` directory.
=== Run native image
Like a normal executable file, launch this example with ``target/nacos-config-2.4.x-example``,
You can observe output similar to the following:
```shell
2022-12-22T16:28:51.006+08:00 INFO 75439 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8888 (http) with context path ''
2022-12-22T16:28:51.008+08:00 INFO 75439 --- [ main] c.a.cloud.imports.examples.Application : Started Application in 0.653 seconds (process running for 0.662)
```
You can see that the application starts up much faster.
We can see the memory usage through ` vmmap pid | grep Physical ` command
The memory usage of applications started using native image is as follows
```
Physical footprint: 59.2M
Physical footprint (peak): 59.2M
```
The memory usage of starting normal Java applications is as follows
```
Physical footprint: 214.0M
Physical footprint (peak): 256.8M
```
As you can see, the memory usage is greatly reduced when the Java application is launched using the native image.
After the application is started, its abilities are the same as if it were started through a jar.

Binary file not shown.

After

Width:  |  Height:  |  Size: 288 KiB

@ -97,3 +97,6 @@ public class UserConfig {
验证动态刷新
访问 http://localhost:8888
再从 nacos 修改配置, 再次访问即可验证动态配置生效
### Native Image构建
请参考`spring-cloud-alibaba-docs`中的`graalvm.adoc`文档

@ -97,3 +97,6 @@ public class UserConfig {
Verify dynamic refresh
access http://localhost:8888
Then modify the configuration from nacos, and visit again to verify that the dynamic configuration takes effect.
### Build Native Image
Please refer to `graalvm.adoc` document in `spring-cloud-alibaba-docs`

@ -210,3 +210,5 @@ Nacos为用户提供包括动态服务发现配置管理服务管理等服
如果您对 Spring Cloud Nacos Discovery 有任何建议或想法,欢迎在 issue 中或者通过其他社区渠道向我们提出。
### Native Image构建
请参考`spring-cloud-alibaba-docs`中的`graalvm.adoc`文档

@ -222,3 +222,5 @@ Nacos makes it easier and faster to construct, deliver and manage your microserv
If you have any ideas or suggestions for Nacos Discovery starter, please don't hesitate to tell us by submitting github issues.
### Build Native Image
Please refer to `graalvm.adoc` document in `spring-cloud-alibaba-docs`
Loading…
Cancel
Save