赞
踩
2022-11-25,SpringBoot 3.0.0 GA版本发布,带了Web Javaer万众期待的Cloud Native特性,这也意味着占据Java Web圈半壁江山的Spring框架正式进入真正的云原生时代。笔者作为一名多年的Java Web开发者,异常激动和兴奋,因为尽管java生态圈在全球开发领域占据非常大的份额,国内各类IT企业对Java已产生了很大的依赖性,简单来说Java为我们创造了很多价值,常年沉浸于Java开发工作,也发现了Java相比其他语言的缺陷与不足,尤其是进入容器化、云原生时代,其缺点尤为明显,主要表现在启动慢、占用内用大、笨重。Spring官方也一直在改进这些问题,但在3.0之前,一直没有好的解决方案,今天我们就来在Windows平台上尝鲜体验一下Spring Boot 3.0中的native特性。
Spring Boot通过GraalVM(据说Oracle会将社区版捐献到OpenJDK中)
来支持native images,取代了实验性的Spring Native项目。
GraalVM 本机映像是独立的可执行文件,运行不依赖JVM,可以通过提前处理已编译的 Java 应用程序来生成。Native Image通常具有较小的内存占用,并且启动速度比 JVM 对应项更快。在Windows上可编译为本地执行运行的exe程序。
与为 JVM 编写的传统应用程序不同,GraalVM 本机映像应用程序需要提前处理才能创建可执行文件。
这里要注意,Java应用程序要支持编译为Native Image,必须有一些前提条件,主要包括
总之,要编译成Native Image,必须消除程序中的动态元素
SpringBoot 3.0中上述这些静态化的额外操作已基本上通过Spring Aot在编译时动态处理,开发者无需额外的配置。
具体的处理细节大家可参考SpringBoot的官方文档
请前往GraalVM官网https://www.graalvm.org/downloads/ 下载 GraalVM Community 22.3
,注意当前支持的Springboot的GraalVM版本必须是22.3
笔者这里下载的Java版本为17,如下图
安装GraalVM的方法与安装JAVA方法大致相同,GraalVM中包括了JDK,同时还需要安装native-image工具
注意该工具在编译时会自动检测是否存在,不存在时会自动下载,第一次下载会很慢。这里可以手动预先下载,并解压到GraalVM同目录下。
这里下载的文件为native-image-installable-svm-java17-windows-amd64-22.3.0.jar
如下图所示
这是笔者安装完后的文件夹结构
配置环境变量PATH,JAVA_HOME
setx /M PATH "C:\Progra~1\Java\<graalvm>\bin;%PATH%"
setx /M JAVA_HOME "C:\Progra~1\Java\<graalvm>"
测试安装是否OK,如下图
编译native image必须依赖VC++的编译环境,这里必须使用微软官方的vc++编译工具Visual Studio,笔者这里使用的最新版本2022,下面为官方描述
To use Native Image on Windows, install Visual Studio and Microsoft Visual C++ (MSVC).
There are two installation options:
* Install the Visual Studio Build Tools with the Windows 10 SDK
* Install Visual Studio with the Windows 10 SDK
You can use Visual Studio 2017 version 15.9 or later.
The `native-image` builder will only work when it is run from the **x64 Native Tools Command Prompt**.
The command for initiating an x64 Native Tools command prompt varies according to whether you only have the Visual Studio Build Tools installed or if you have the full Visual Studio 2019 installed.
从上可知,Visual Studio 2017 version 15.9 or later
均可。
打开Visual Studio Installer,勾选如下图中三个组件
安装完成后,需要配置VC++的编译环境变量PATH,INCLUDE,LIB
看相关文章也可不配置,但是执行编译时必须在X64 Native Tools Command Prompt for VS 2022控制台中执行,但笔者安装的环境下编译失败,提示找到 stdio.h 等错误,如果网友也遇到同样,欢迎提供更好的解决方案
LIB=C:\Program Files (x86)\Windows Kits\10\Lib\10.0.20348.0\um\x64;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.20348.0\ucrt\x64;D:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.16.27023\lib\x64
INCLUDE=C:\Program Files (x86)\Windows Kits\10\Include\10.0.20348.0\ucrt;C:\Program Files (x86)\Windows Kits\10\Include\10.0.20348.0\um;C:\Program Files (x86)\Windows Kits\10\Include\10.0.20348.0\shared;D:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.16.27023\include
PATH=D:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.16.27023\bin\HostX64\x64
可使用https://start.spring.io/来生成项目模板,完整的项目pom.xml如下
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>3.0.0</version> </parent> <modelVersion>4.0.0</modelVersion> <groupId>org.example</groupId> <artifactId>spring_native_test</artifactId> <version>1.0-SNAPSHOT</version> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> <properties> <maven.compiler.source>17</maven.compiler.source> <maven.compiler.target>17</maven.compiler.target> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties> <build> <plugins> <plugin> <groupId>org.graalvm.buildtools</groupId> <artifactId>native-maven-plugin</artifactId> </plugin> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
编写一个简单的spring mvc应用
package org.example; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; /** * Created on ${DATE}. * * @author ${USER} */ @RestController @SpringBootApplication public class MyApplication { @RequestMapping("/") String home() { return "Hello World!"; } public static void main(String[] args) { SpringApplication.run(MyApplication.class, args); } }
配置项目,注意这里必须选择GraalVM作为项目的SDK
调试运行,正常启动
在项目根目录下执行
mvn -Pnative native:compile
下图为最终执行成功的输出
在项目target目录下可以找到spring_native_test.exe
文件
native image运行控制台输出如下图
jvm运行控制台输出如下图
jar(JVM) | 本地exe(native image) | |
---|---|---|
文件大小 | 18M | 69M |
启动耗时 | 1.209s | 0.098s |
内存占用 | 106M | 46m |
根据上述对比结果,尽管是一个最简单的springboot程序,但在启动耗时上native具有明显的优势,达到毫秒级,占用内存少了一半多。
由于是一项新技术,其推广和普及肯定需要一段时间,但在一些新的小型应用中,完全可以试试手,毕竟尽量native用不了,还有jvm可以兜底,我们并需要为此做额外的工作。
最后,希望java web能通过native的特性,真正的适配云原生。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。