preface
Spring Native Beta was released in March of this year, and I was hoping to wait until the official release to check it out, but don’t wait, let’s try it now.
The spring Framework, Spring Boot, Spring Cloud, etc., is now free to share with Java programmers who read this article. They need to collect their own notes
Microservices +MySQL+ distributed +SSM framework +Java+Redis+ data structure and algorithm + network +Linux+Spring bucket +JVM+ high concurrency + major learning mind map + interview set
Spring Native profile
As we all know, traditional Spring applications have to rely on the Java Virtual Machine (JVM) to run. Spring Native provides an alternative way to run and deploy Spring applications (currently Java and Kotlin only) without the NEED for a JVM. Compile your Spring application to a native image with GraalVM.
Spring Native characteristics
1. Spring Native applications can be independently deployed as an executable without the need for a JVM environment;
2, the application immediately start, under normal circumstances the application start time < 100ms;
3. Instant peak performance;
4, less memory consumption;
Spring Native shortcomings
Spring Native apps launch so quickly at a cost, compared to JVM apps:
1. Heavier build and longer build time;
2. Less runtime optimization;
3. Many Java features are limited;
4, many features are still very immature;
Spring Native application scenarios
1. Spring Cloud Serverless;
2. Run Spring microservices in a cheaper and more durable way;
3. Well suited to Kubernetes platforms, such as VMware Tanzu;
4. Create better container images for Spring applications;
Differences between Spring Native and the JVM
1. Static analysis of applications during Spring Native construction;
2. Spring Native builds to remove unused components;
3. Spring Native reflection, resources and dynamic proxy need to be configured;
4. The Classpath is fixed when Spring Native is built;
5. Spring Native has no class lazy loading, and the executable contains all contents loaded into memory at startup;
6. Spring Native builds run some code;
7. Spring Native has some limitations for Java applications;
GraalVM profile
At the heart of Spring Native is Oracle’s dark technology: GraalVM.
GraalVM is a full-stack general-purpose virtual machine developed by Oracle. It features high performance and cross-language interaction. GraalVM not only supports JVM based languages such as Java, Scala, Groovy and Kotlin, but also llVM-based languages such as C and C++. Other languages like JavaScript, Ruby, Python, and R are also supported to increase the speed and throughput of multiple languages.
GraalVM has the following features.
- Run code more efficiently and quickly
- Can interact directly with most programming languages
- Embedding multiple languages using the Graal SDK
- Create a precompiled native image
- Provides a range of tools to monitor, debug, and configure all code
Focus on native mirroring:
$ javac HelloWorld.java
$ time java HelloWorld
user 0.070s
$ native-image HelloWorld
$ time ./helloworld
user 0.005s
Copy the code
GraalVM can be precompiled into native images, which greatly improves startup time and reduces memory footprint for JVM applications. Now you know why Spring Native starts so fast!
It is through GraalVM that Spring Native provides a lightweight way to run traditional Spring applications that can be easily implemented by integrating Spring Native projects without modifying any traditional application code.
Start to try
There are two ways to build Spring Native applications:
Use Spring Boot Buildpacks to build a lightweight container containing native executables.
2. Use GraalVM Native Image Maven plugin to generate an executable file containing the native image;
This article uses the first way to taste!
1. Environmental requirements
This method requires the Docker environment to be installed:
- Linux must be configured to run as a non-root user
- The Mac requires a maximum memory of 8 GB or higher
Since I have installed it locally, I won’t demonstrate it here, so I won’t click here to read it for reference, or follow the public account: Java Technology Stack, and search for it in the history article.
2. Add dependencies
Spring Native is already available in start.spring. IO. Add a “Spring Native” dependency to the page, as shown below:
Spring the Boot:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.4.5</version>
<relativePath/>
</parent>
Copy the code
Spring Native:
<dependencies>
<dependency>
<groupId>org.springframework.experimental</groupId>
<artifactId>spring-native</artifactId>
<version>${spring-native.version}</version>
</dependency>
</dependencies>
Copy the code
Note dependent versions:
The latest version of Spring Native is 0.9.2, and only Spring Boot 2.4.5 is supported
3. Add the Spring AOT plugin
Add Spring AOT plugin:
<build>
<plugins>
<plugin>
<groupId>org.springframework.experimental</groupId>
<artifactId>spring-aot-maven-plugin</artifactId>
<version>0.9.2</version>
<executions>
<execution>
<id>test-generate</id>
<goals>
<goal>test-generate</goal>
</goals>
</execution>
<execution>
<id>generate</id>
<goals>
<goal>generate</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
Copy the code
The Spring AOT plug-in performs the required up-front conversions to improve compatibility with native images.
4. Enable native mirroring
Add the following configuration to the Spring Boot Maven plugin:
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<image>
<builder>paketobuildpacks/builder:tiny</builder>
<env>
<BP_NATIVE_IMAGE>true</BP_NATIVE_IMAGE>
</env>
</image>
</configuration>
</plugin>
Copy the code
5. Add Maven repository support
Spring Native dependencies and plug-ins need to be downloaded from the Spring repository, and the following configuration needs to be added.
<repositories>
<repository>
<id>spring-release</id>
<name>Spring release</name>
<url>https://repo.spring.io/release</url>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>spring-release</id>
<name>Spring release</name>
<url>https://repo.spring.io/release</url>
</pluginRepository>
</pluginRepositories>
Copy the code
If you can’t download Native dependencies and plug-ins properly, check Maven’s settings.xml file:
<mirror>
<id>nexus-aliyun</id>
<mirrorOf>*,!spring-release</mirrorOf>
<name>Nexus aliyun</name>
<url>http://maven.aliyun.com/nexus/content/groups/public</url>
</mirror>
Copy the code
Change mirrorOf from * to: *,! spring-release
6. Add test interfaces
Add a test interface to test the feasibility of native applications once they start.
/** * wechat: javataozi888 */
@SpringBootApplication
@RestController
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class);
}
@RequestMapping("/native/hi")
@ResponseBody
public String hiNative() {
return "hi native application..."; }}Copy the code
All code for this article has been uploaded to: github.com/javastacks/…
7. Build native apps
Maven plugin build command:
mvn spring-boot:build-image
This creates a Linux container that builds native applications using the GraalVM native image compiler, which is installed locally only by default.
Run in IDEA plugin:
Once configured, start building:
You’ll see a lot of these errors, don’t bother, this one will be removed in the future.
The e final build, a simple Spring Boot application, took me four minutes.
8. Run native apps
You can run native apps the way you normally run Docker images:
docker run –rm -p 8080:8080
You can also write docker-comemage. yml files in your project, which will not be demonstrated here. If you are interested, you can follow the public id: Java Technology Stack, search the history article and read the Docker series.
Typically, running a native application takes less than 100 milliseconds, while running a JVM-based application takes about 15 seconds.
Whether this is the case, take a look!
Oh, my God. 82 milliseconds. That’s fast.
To access the interface we wrote earlier:
http://localhost:8080/native/hi
The output is normal, and the native application verification is complete.
Also, an executable JAR package is generated in the target directory:
Then we run it in a traditional JVM environment:
Java jar – spring – the boot – native – 1.0. The jar
Startup time: 1.903 seconds. While this may not seem like a big difference, native applications (0.082 seconds) are 23 times faster than JVM startup times, which can be a big difference depending on the amount of code.
Of course, this is just a reference time for my tests, but it does show that native applications run much faster than JVMS!
Let’s check the size of the bag again
View the Docker image you just generated:
docker image ls
View the jVM-based executable JAR package:
The size of the Docker image is 80.7 MB, while the executable JAR package running on the JVM is less than 20 MB.
This is because the native image not only contains the required items from JDK and Spring used in the application, but also contains a minimal OS layer, so it is definitely much larger than the previous one.
Summary This article introduces the characteristics of Spring Native, and demonstrates the Native application based on Docker image.
All demo code for this article has been uploaded to:
Github.com/javastacks/…
All interested can Star under the repository, including previously written Spring Boot tutorial and sample source code.
Of course, in addition to the Docker image, you can also use the Maven plugin method, which does not need Docker, but requires the installation of the native image compiler GraalVM, the reason is the same, here will not demonstrate, interested can refer to:
Docs. Spring. IO/spring – nati…
If Docker is used, the first way is definitely better, all dependencies are packaged into a single image, avoiding environmental pollution.
To sum up, Spring Native can run without a JVM, be slow to build, fast to start up, consume less memory, and perform fewer optimizations. In addition, there are many Limitations to Java features, such as: Reflection, dynamic proxy, etc., need to be pre-configured because Java is a dynamically linked language and native applications need to be pre-compiled, so features like reflection and dynamic proxy are limited.
In addition, Spring Native is still in Beta testing, so there will definitely be some problems and changes in the future, but I will keep an eye on them. I will update more articles about the latest technologies in the Java series in the future. Please continue to pay attention!
All the contents of this section refer to the latest documents on the official website. It can be said that it is the first person to eat crab. If you feel that my article is harvested for you, move your hands and give a look and forwarding.