|
|
|
@ -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.json:Resource hint file
|
|
|
|
|
- reflect-config.json:Reflection definition hint file
|
|
|
|
|
- serialization-config.json:Serialization hint file
|
|
|
|
|
- proxy-config.json:Proxy hint file
|
|
|
|
|
- jni-config.json:JNI 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.
|