GraalVM和Spring Native尝鲜一步步让Springboot启动飞起来66ms完成启动
作者:LarryDpk 发布时间:2023-07-19 10:34:35
简介
GraalVM
是高性能的JDK,支持Java/Python/JavaScript等语言。它可以让Java变成二进制文件来执行,让程序在任何地方运行更快。这或许是Java与Go的一场战争?
下载安装GraalVM
安装GraalVM
首先到官网下载,我是直接到GitHub Release Page下载的,请下载对应的系统包,我下载如下:
graalvm-ce-java11-darwin-amd64-22.3.0.tar.gz
下载后解压到某个目录,我的如下:
/Users/larry/Software/graalvm-ce-java11-22.3.0
接着测试对应的程序是否可以正常执行,如java --version
。在Mac上会报错如下:
is damaged and can’t be opened.
所以需要执行下面语句:
$ sudo xattr -r -d com.apple.quarantine /Users/larry/Software/graalvm-ce-java11-22.3.0
注意修改对应的目录。
然后就可以执行了:
$ ./java --version
openjdk 11.0.17 2022-10-18
OpenJDK Runtime Environment GraalVM CE 22.3.0 (build 11.0.17+8-jvmci-22.3-b08)
OpenJDK 64-Bit Server VM GraalVM CE 22.3.0 (build 11.0.17+8-jvmci-22.3-b08, mixed mode, sharing)
安装native-image
这个工具用来把Java程序转化为本地二进制包,安装如下:
$ ./gu install native-image
Downloading: Component catalog from www.graalvm.org
Processing Component: Native Image
Downloading: Component native-image: Native Image from github.com
Installing new component: Native Image (org.graalvm.native-image, version 22.3.0)
配置环境
配置环境变量
因为这个GraalVM还不够成熟,我不想一直使用,就通过一个命令来切换,配置如下:
export GraalVM_HOME=/Users/larry/Software/graalvm-ce-java11-22.3.0/Contents/Home
alias switchOnGraalVM='export PATH=$GraalVM_HOME:$PATH'
alias switchOnGraalVMJavaHome='export JAVA_HOME=/Users/larry/Software/graalvm-ce-java11-22.3.0/Contents/Home'
alias switchOffGraalVM='export PATH=`echo $PATH | tr ":" "\n" | grep -v "graalvm" | tr "\n" ":"`'
alias switchOffGraalVMJavaHome='export JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk1.8.0_212.jdk/Contents/Home'
配置IDEA
可以在IDEA上配置对应的JDK,这样开发的时候可以使用:
整合Spring Native与Spring Boot
普通Spring Boot程序
新来创建一个普通的Spring Boot Web程序,主要Java代码如下:
@SpringBootApplication
@RestController
@RequestMapping("/")
public class SpringbootNativeGraalVMMain {
public static void main(String[] args) {
SpringApplication.run(SpringbootNativeGraalVMMain.class, args);
}
@GetMapping("/hi-graalvm")
public String hi() {
return "This message is from Spring Boot built/run by GraalVM/Spring Native";
}
}
启动时长为1.193秒,还不错。我电脑还不错。
整合Spring Native
添加依赖:
<dependency>
<groupId>org.springframework.experimental</groupId>
<artifactId>spring-native</artifactId>
<version>${spring-native.version}</version>
</dependency>
添加插件,这个插件非常重要,不然会有各种错误:
<build>
<plugins>
<plugin>
<groupId>org.springframework.experimental</groupId>
<artifactId>spring-aot-maven-plugin</artifactId>
<version>0.11.5</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>
添加以下插件来打包生成可执行程序:
<profiles>
<profile>
<id>native</id>
<properties>
<repackage.classifier>exec</repackage.classifier>
<native-buildtools.version>0.9.11</native-buildtools.version>
</properties>
<dependencies>
<dependency>
<groupId>org.junit.platform</groupId>
<artifactId>junit-platform-launcher</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.graalvm.buildtools</groupId>
<artifactId>native-maven-plugin</artifactId>
<version>${native-buildtools.version}</version>
<extensions>true</extensions>
<executions>
<execution>
<id>test-native</id>
<phase>test</phase>
<goals>
<goal>test</goal>
</goals>
</execution>
<execution>
<id>build-native</id>
<phase>package</phase>
<goals>
<goal>build</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
然后通过以下命令来build包,时间会长很多,因为要转化为二进制可执行文件:
$ mvn clean package -Pnative
两分多钟后完成,生成了一个可执行文件,执行如下:
$ target/spring-boot-native-graalvm
结果只花了0.066秒,即66毫秒就可以了,这也太快了吧。
访问接口也是正常的:
用Docker启动
先启动本地的Docker,然后添加依赖如下:
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<classifier>${repackage.classifier}</classifier>
<image>
<builder>paketobuildpacks/builder:tiny</builder>
<env>
<BP_NATIVE_IMAGE>true</BP_NATIVE_IMAGE>
</env>
</image>
</configuration>
</plugin>
通过以下命令打出Docker镜像:
mvn spring-boot:build-image
可能会花费很长时间,需要下载一些工具与镜像。
打包成功后,多了镜像:
$ docker images | grep graalvm
spring-boot-native-graalvm 1.0-SNAPSHOT d2c8d5c52a3c 42 years ago 85.8MB
启动如下:
$ docker run --rm spring-boot-native-graalvm:1.0-SNAPSHOT -p 8080:8080
启动时间为59ms,更短了。
注意
直接通过
native-image
命令来将jar包转化为可执行文件,如遇到各种问题,劝大家放弃尝试,这也是Spring Native
存在的价值。别问我为什么知道,哈哈~~要注意切换对应的Java程序和Java Home,不然build包会报错。
看Spring Native的包名是experimental的,离生产应该还有距离,不要轻易在生产上用。
代码
代码请看GitHub: https://github.com/LarryDpk/pkslow-samples
来源:https://www.pkslow.com/archives/spring-boot-native-graalvm


猜你喜欢
- 本文实例为大家分享了Android App获取屏幕旋转角度的具体代码,供大家参考,具体内容如下一、获取屏幕旋转角度的方法是:int rota
- Random类介绍Random类一个用于产生 伪随机 数字的类。这里的伪随机表示有随机性但是可以基于算法模拟出随机规律。Random类的构造
- 最近学习JavaFx,发现网上大概只有官方文档可以查阅,学习资料较少,写个拼图游戏供记录。。大概说一下思路:1.面板的构建:面板采用Grid
- 前言:synchronized 在 JDK 1.5 之前性能是比较低的,在那时我们通常会选择使用 Lock 来替代 synchronized
- 背景:本人不是Java开发人员,经过四年多的历练,可以说是一枚BI攻城师了吧,最近粗糙的写了一个Portal来集成cognos报表,下面就入
- 只需要实现下面2段代码即可实现对网络连接状态的监听,千万别忘了在Manifest.xml里面添加网络访问权限哦。 1、定义广播 * Net
- 本文实例为大家分享了Unity使用射线实现贴花系统,供大家参考,具体内容如下老规矩,直接上代码:using System.Collectio
- 这篇文章主要介绍了SPRING IOC注入方式过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋
- 前言Android 很多场合需要使用到数据加密,比如:本地登录密码加密,网络传输数据加密,等。在android 中一般的加密方式有如下:亦或
- 前言:前面几篇讲了自定义控件绘制原理Android自定义控件基本原理详解(一) ,Android自定义控件之自定义属性(二) ,Androi
- 本文为大家分享了Android studio安装与配置,具体内容如下1、首先下载Android studio安装包,可以从http://ww
- 如果我们遇到把excel表格中的数据导入到数据库,首先我们要做的是:将excel中的数据先读取出来。因此,今天就给大家分享一个读取Excel
- Lambda,希腊字母λ,在C#编程语言中,被引入为Lambda表达式,表示为匿名函数(匿名方法)。编程时离不开函数,
- 介绍今天上班的时候有个哥们问我怎么去实现一个按钮式的进度条,先来看看他需要实现的效果图。和普通的圆形进度条类似,只是中间的地方有两个状态表示
- 前言 我们都知道,finally在捕获异常的操作中,总是最
- 一、什么是建造者模式建造者模式也称生成器模式 定义:将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示(依赖倒转)产品
- GSYVideoPlayerGSYVideoPlayer官方地址GSYVideoPlayer 一个基于IJkPlayer的播放器支持调节声音
- 本文实例为大家分享了SpringBoot实现分页功能的具体代码,供大家参考,具体内容如下新建demo\src\main\java\com\e
- 本文实例讲述了Android游戏开发学习①弹跳小球实现方法。分享给大家供大家参考。具体如下:在学习了一点点Android之后,觉得有必要记录
- 什么是指纹解锁技术根据人的指纹来验证是否能够解锁的技术,类似于通过输入密码来解锁,都是通过一定的数字特征来解锁。指纹解锁技术原理理解首先说明