0


Spring Native 解放 JVM

一、Spring Native 是什么

Spring Native

可以通过

GraalVM

Spring

应用程序编译成原生镜像,提供了一种新的方式来部署

Spring

应用。与

Java

虚拟机相比,原生镜像可以在许多场景下降低工作负载,包括微服务,函数式服务,非常适合容器和

Kubernetes

。使用原生镜像有明显优势,如快速启动,提高峰值性能以及降低内存消耗。

Spring Native

支持

Java

Kotlin

这个项目的目标是寻找

Spring JVM

的替代方案,提供一个能将应用程序打包,并运行在轻量级容器的方案。期望能够在

Spring Native

中支持所有的

Spring

应用程序(几乎不用修改代码)。

原生(本地)镜像是一种将

Java

代码构建为独立可执行文件的技术。该可执行文件包括应用程序类、其依赖项的类、运行时库类以及来自

JDK

的静态链接本地代码。

JVM

被打包到原生镜像中,因此在目标系统上不需要任何

Java

运行环境,但构建产物依赖于平台。因此,需要为每个支持的目标系统进行一次构建,在使用

Docker

等容器技术时会更加简单,将容器构建为一个目标系统,可以部署到任何

Docker

运行时。

二、优点

Spring Native

的基础是

GraalVM

,而

GraalVM

是使用

Java

静态编译,将

Java

字节码编译为汇编代码,即二进制

native

程序,他摒弃了

JVM

,这是成就它所有优点的根本原因。
【1】编译出来的原生

Spring

应用可以作为一个独立的可执行文件进行部署(不需要安装

JVM


【2】几乎瞬时的启动(一般小于

100

毫秒)
【3】瞬时的峰值性能
【4】更低的资源消耗

三、局限性

GraalVM

项目也有一些缺点和权衡,希望随着时间的推移有所改进:
【1】构建本地映像是一个繁重的过程,比

JVM

更长的构建时间;
【2】相比于传统的

Java

运行方式,运行时优化不足;
【3】不能直接支持反射、动态代理等动态特性;
【4】现在处于实验阶段,生态比较少;

四、原生镜像(native image)和常规 JVM 程序的区别

【1】在构建时会从主入口点对应用程序进行静态分析。
【2】在构建时会移除未使用的代码。
【3】需要配置反射、动态代理等。
【4】类路径

ClassPath

在构建时就已经确定。
【5】没有类延迟加载:可执行文件中所有的内容都会在启动时加载到内存中。
【6】在构建时就运行了一些代码。
【7】构建原生镜像还存在一些局限性。
【8】一些

Java

切面类的特性未得到完全支持。

五、前置条件:GraalVM

通用递归应用和算法语言虚拟机

Graal VM

是一个高性能的

JDK

发行版,专为

Java

和其他

JVM

语言编写,同时支持

JavaScript

Ruby

Python

和其他几种语言。

GraalVM

的多语言能力使得在一个应用程序中混合使用多种编程语言成为可能,同时消除了不同语言间互相调用的成本。它提供了一个原生镜像生成器

Native Image builder

,这是一个从

Java

应用中生成原生代码并将其与

VM

一起打包成独立可执行文件的工具。

Spring Boot Maven

Gradle Plugin

除了少数 例外情况(

Mockito

目前不支持原生测试),正式支持该工具。

Ahead-Of-Time(AOT)

编译是将高级

Java

代码编译成本地可执行代码的过程。通常由

JVM

的即时编译器

JIT

在运行时进行编译,这样可以在执行应用程序时进行观察和优化。在

AOT

编译的情况下,这一优势就不复存在了。

通常,在进行

AOT(Ahead-of-Time)

编译之前,可以选择进行一个单独的步骤,称为

AOT

处理,即从代码中收集元数据并提供给

AOT

编译器。将这两个步骤分开是有意义的,因为

AOT

处理可以是针对特定框架的,而

AOT

编译器更加通用。下面的图片给出了一个概览:

Java

平台的另一个特点是,只需将

JAR

放入类路径,就能在目标系统上进行扩展。通过启动时的反射和注解扫描,就能在应用中获得扩展行为。不幸的是,这会减慢启动时间,而且不会带来任何好处,尤其是对于云原生应用,因为在云原生应用中,服务器运行时和

Java

基类都打包到了

JAR

中。因此,可以放弃这一功能,然后可以使用闭环优化

Closed World Optimization

来构建应用。

详细信息参考:JIT即时编译与AOT提前编译; GraalVM :官网

六、Spring Native 基础环境搭建

**【1】必须安装

Docker

:** 可以参考 Windows10 Docker Desktop安装 ,同时注意要能够以非

root

用户启动和运行。可以通过使用

docker run hello-world 

(不包含

sudo

)命令检查

Docker daemon

是否可用。
**【2】快速创建一个

SpringBoot

项目**。
**【3】添加

Spring Native

依赖:** 必须在项目中手动加入和配置。对于

AOT

处理,有一个单独的

Maven

Gradle

插件,它并没有合并到

Spring Boot

插件中。

org.springframework.experimental:spring-native

提供了

native

配置的

API

,例如

@NativeHint

这些

Spring

运行成

native image

的注解类。

<dependency><groupId>org.springframework.experimental</groupId><artifactId>spring-native</artifactId><version>0.9.1</version></dependency>

**【4】添加

Spring AOT

插件:**

Spring AOT

插件执行代码的提前转换,有助于改善原生镜像的占用空间和修复

native image

的兼容性。

<plugin><groupId>org.springframework.experimental</groupId><artifactId>spring-aot-maven-plugin</artifactId><version>0.9.1</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>

**【5】开启

native image

支持:**

Spring Boot

Spring Boot Buildpacks support

可以将

Spring Boot

应用程序打包成一个容器。

native image buildpack

可以通过

BP_NATIVE_IMAGE

环境变量开启。

<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>

【6】构建本地应用程序: 通过此命令,可以创建一个使用

GraalVM native image compiler

构建的

Linux

容器,默认情况下,这个镜像是在本地。

mvn spring-boot:build-image

【7】原生镜像构建:

Profile

将在打包阶段调用构建中的

native-image

编译器。通过在

Maven package

命令中提供

native Profile

,就可以构建原生镜像了:

mvn clean package -Pnative
<profiles><profile><id>native</id><build><plugins><plugin><groupId>org.graalvm.buildtools</groupId><artifactId>native-maven-plugin</artifactId><version>0.9.17</version><executions><execution><id>build-native</id><goals><goal>build</goal></goals><phase>package</phase></execution></executions></plugin><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><configuration><classifier>exec</classifier></configuration></plugin></plugins></build></profile></profiles>
标签: spring jvm java

本文转载自: https://blog.csdn.net/zhengzhaoyang122/article/details/136097803
版权归原作者 程序猿进阶 所有, 如有侵权,请联系我们删除。

“Spring Native 解放 JVM”的评论:

还没有评论