暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

Spring Native, 0.1秒启动你的java应用

java知路 2021-08-11
4036

最近,Spring 发布了 Spring Native 的 beta 版本,该功能已经在 start.spring.io 上可用了。


这些原生的 Spring 应用可以作为一个独立的可执行文件进行部署(不需要安装 JVM),并且还能提供有趣的特征,包括几乎瞬时的启动(一般会小于 100 毫秒)、瞬时的峰值性能以及更低的资源消耗,其代价是比 JVM 更长的构建时间和更少的运行时优化。


一个普通java的启动时间大概一秒多

用上spring native后



1.概述

Spring Native 为使用 GraalVM 原生镜像编译器编译 Spring 应用为本地可执行文件提供支持。

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

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

GraalVM 项目也有一些缺点和权衡,希望随着时间的推移有所改进。构建本地映像是一个繁重的过程,比常规应用程序要慢,预热后的运行时优化也更少。最后,比起 JVM 很多场景下还不成熟。

常规 JVM 和此本机映像平台之间的主要区别:

  • 在构建时会从主入口点对应用程序进行静态分析。

  • 在构建时将未使用的零件删除。

  • 反射,资源和动态代理需要配置。

  • 类路径在构建时是固定的。

  • 没有类延迟加载:可执行文件中附带的所有内容都将在启动时加载到内存中。

  • 一些代码将在构建时运行。

  • 一些 Java 切面类的特性未得到完全支持。详情

此项目的目标是孵化对 Spring Native
(Spring JVM的替代方案)的支持,并提供旨在打包到轻量级容器中的本地部署选项, 目标是在此新平台上直接支持 Spring 应用而不需要修改代码。

示例项目

        <parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.5.2</version>
    <relativePath/> <!-- lookup parent from repository -->
    </parent>

    现在springboot 2.4.5以上的版本支持比较好

    添加 aot插件

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

      对比JIT和AOT,各自有什么优点与缺点

      JIT:吞吐量高,有运行时性能加成,可以跑得更快,并可以做到动态生成代码等,但是相对启动速度较慢,并需要一定时间和调用频率才能触发 JIT 的分层机制

      AOT:内存占用低,启动速度快,可以无需 runtime 运行,直接将 runtime 静态链接至最终的程序中,但是无运行时性能加成,不能根据程序运行情况做进一步的优化





      完整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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
        <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.5.2</version>
        <relativePath/> <!-- lookup parent from repository -->
        </parent>
        <groupId>com.example</groupId>
        <artifactId>demo-native-maven</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <name>demo-native-maven</name>
        <description>Demo project for Spring Boot</description>
        <properties>
        <java.version>11</java.version>
        <repackage.classifier/>
        <spring-native.version>0.10.1</spring-native.version>
        </properties>
        <dependencies>
        <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
        <groupId>org.springframework.experimental</groupId>
        <artifactId>spring-native</artifactId>
        <version>${spring-native.version}</version>
        </dependency>


        <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
        </dependency>
        </dependencies>


        <build>
        <plugins>
        <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>
        <plugin>
        <groupId>org.springframework.experimental</groupId>
        <artifactId>spring-aot-maven-plugin</artifactId>
        <version>${spring-native.version}</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>
        <repositories>
        <repository>
        <id>spring-releases</id>
        <name>Spring Releases</name>
        <url>https://repo.spring.io/release</url>
        <snapshots>
        <enabled>false</enabled>
        </snapshots>
        </repository>
        </repositories>
        <pluginRepositories>
        <pluginRepository>
        <id>spring-releases</id>
        <name>Spring Releases</name>
        <url>https://repo.spring.io/release</url>
        <snapshots>
        <enabled>false</enabled>
        </snapshots>
        </pluginRepository>
        </pluginRepositories>


        <profiles>
        <profile>
        <id>native</id>
        <properties>
        <repackage.classifier>exec</repackage.classifier>
        <native-buildtools.version>0.9.1</native-buildtools.version>
        </properties>
        <dependencies>
        <dependency>
        <groupId>org.graalvm.buildtools</groupId>
        <artifactId>junit-platform-native</artifactId>
        <version>${native-buildtools.version}</version>
        <scope>test</scope>
        </dependency>
        </dependencies>
        <build>
        <plugins>
        <plugin>
        <groupId>org.graalvm.buildtools</groupId>
        <artifactId>native-maven-plugin</artifactId>
        <version>${native-buildtools.version}</version>
        <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>


        </project>




        mvn -Pnative-image package

        会在target生成可执行文件


        com/oracle/svm/reflect显示了由于反射而包括的条目。



        遇到的坑

         native-image打包为本地镜像时候出错

          PS C:\Users\cc\Desktop\java> native-image Example
          [example:7472] classlist: 1,642.36 ms, 0.96 GB
          [example:7472] setup: 586.88 ms, 0.96 GB
          Error: Default native-compiler executable 'cl.exe' not found via environment variable PATH
          Error: To prevent native-toolchain checking provide command-line option -H:-CheckToolchain
          Error: Use -H:+ReportExceptionStackTraces to print stacktrace of underlying exception
          Error: Image build request failed with exit status 1
          PS C:\Users\cc\Desktop\java> a



          安装Visual Studio

          选择单个组件

            INCLUDE=C:\Program Files (x86)\Windows Kits\10\Include\10.0.17134.0\ucrt;C:\Program Files (x86)\Windows Kits\10\Include\10.0.17134.0\um;C:\Program Files (x86)\Windows Kits\10\Include\10.0.17134.0\shared;D:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.16.27023\include.;


              LIB=C:\Program Files (x86)\Windows Kits\10\Lib\10.0.17134.0\um\x64;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.17134.0\ucrt\x64;D:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.16.27023\lib\x64;



              在PATH中添加:

                C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.16.27023\bin\HostX64\x64



                文章转载自java知路,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

                评论