首页 > 其他分享 >GraalVM和Spring Native尝鲜,一步步让Springboot启动飞起来,66ms完成启动

GraalVM和Spring Native尝鲜,一步步让Springboot启动飞起来,66ms完成启动

时间:2023-01-29 18:11:41浏览次数:60  
标签:66ms Springboot 启动 Spring 22.3 native Native graalvm GraalVM

简介

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


References:

Quick Start Guide

GraalVM Quick Reference

GraalVM Native Image Quick Reference v1

向云原生靠近 | 体验 GraalVM 静态编译字节码,尝试 “超声波 Java” - Quarkus

标签:66ms,Springboot,启动,Spring,22.3,native,Native,graalvm,GraalVM
From: https://www.cnblogs.com/larrydpk/p/17073451.html

相关文章

  • springboot~openfeign开启熔断之后MDC为null的理解
    openfeign开启熔断之后MDC为null,这是有前提的,首先,你的熔断开启后,使用的是线程池的熔断模式,即hystrix.command.default.execution.isolation.strategy=THREAD,或者不写这行,如......
  • SpringBoot3.x SpringCloudGateway与SpringDoc OpenApi整合
     网关的配置文件这个是用来转发各个服务的 /v3/api-docs请求routes:#转发swagger接口-id:openapiuri:http://localhost:${......
  • springboot 怎么启动aop @EnableAspectJAutoProxy
    SpringBoot项目使用aophttps://blog.csdn.net/qq_39176307/article/details/124714191Spring-AOPSpringBoot自动配置和启动SpringAOPhttps://www.bbsmax.com/A/QV5ZX3......
  • springboot配置文件读取顺序
    若application.yml和bootStrap.yml在同一目录下,则bootStrap.yml的加载顺序要高于application.yml,即bootStrap.yml会优先被加载。原理:bootstrap.yml用于应用程序上......
  • HotSpot VM启动时JNI_CreateJavaVM方法执行步骤
    1、确保只有一个线程调用这个方法并且确保只创建一个HotSpotVM实例。因为HotSpotVM创建的静态数据结构无法再次初始化,所以一旦初始化达到某个确定点后,进程空间里就只能有......
  • springboot实现连接多个数据源
    dynamicdatasource导入依赖<dependency><groupId>com.baomidou</groupId><artifactId>dynamic-datasource-spring-boot-starter</artifactId>......
  • win11 启动 wifi 热点
    网络上查到的使用netsh命令,没有用使用下面的命令开启热点@echooffpowershell.exe-encodedCommandWwBXAGkAbgBkAG8AdwBzAC4AUwB5AHMAdABlAG0ALgBVAHMAZQByAFAAcgBvA......
  • Launcher启动器
    由Launcher负责调用HotSpot的核心代码对JVM执行初始化,以及由它负责维护JVM的整个生命周期。Launcher是一种用于启动JVM进程的启动器,并且可以根据类型划分为两种不同的Launch......
  • SpringBoot中配置Redis
    SpringBoot中整合Redis缓存背景:工作中需要用到缓存之前都是用ConcurrentHashMap公司不让用redis那我就小试牛刀一下前端的App、网页在登录时,或是用户在进行一些敏感......
  • 关于pacemaker中资源启动的位置约束Location Constraints
    默认情况,对于业务应用的资源启动在那里,可能是随机的、有时启动在app01上,也可能启动在app02了我们也可以通过手动配置分数的方式,将某个节点的分数配置到极高,无穷大,这样,资......