译文:在GraalVM中部署运行Spring Boot应用
GraalVM是一种高性能的多语言虚拟机,用于运行以JavaScript等基于LLVM的各种语言编写的应用程序。对于Java应用也可作为通常JVM的替代,它更具有性能优势。GraalVM带来的一个有趣功能是它能够在创建JVM应用程序的提前编译(create ahead-of-time:AOT)本机镜像,从而保证了更快的启动时间和更低的内存占用。在本文中,我们将重点介绍如何创建Spring应用的本机二进制文件。
GraalVM Native Image 101
Java应用程序使用编译为字节码javac。在应用程序运行时,JVM将类文件加载到内存中,并分析程序的性能以获取热点。因此名称为“ HotSpot JVM ”。在刚刚在时间(JIT)编译器编译这些重复执行为本机代码应用程序的部分。 但是,JIT编译需要处理器时间和内存,这会影响应用程序的启动时间。
GraalVM原生本机镜像能提前将 JVM应用程序编译为当前机器的机器代码。它静态分析应用程序的字节码,找到所有可以访问的类和方法,并将它们编译为本地可执行文件。输出是特定于平台的可执行二进制文件。
例如,让我们从以下“ Hello World”程序构建原生镜像。
class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello World");
}
}
首先,我们需要使用 javac:
$ javac HelloWorld.java
然后用native-image将这个类文件构建成可执行二进制文件。
$ native-image HelloWorld
要启动应用程序,只需:
$ ./helloworld
Hello World
本机镜像Java限制
GraalVM本机镜像静态分析是需要假设在封闭世界的前提下。它需要在镜像生成期间提前知道所有可能访问的字节码。因此,并非所有Java功能都受支持:例如,不支持动态类的加载/卸载。反射需要配置。CGLIB代理不适用,但是却支持JDK代理,还需要配置。此外,您还需要告诉本机镜像有关所有资源访问的信息。
配置以JSON文档的形式提供。例如,要配置反射,您可以创建以下文件,并使用-H:ReflectionConfigurationFiles命令行标志来指定命令的文件位置native-image。
[
{ "name":"java.lang.Object" },
{ "name":"org.apache.naming.factory.ResourceFactory", "methods" : [{"name": "<init>","parameterTypes":[]}] },
...
]
配置动态代理、JNI和资源访问时都需要创建类似的文件来。但是,手工完成所有这些工作需要很多工作,尤其是在我们处理大型应用程序时。幸运的是,有一个Java代理可以生成配置。它观察在JVM中运行的应用程序的行为,并生成生成本机映像所需的配置文件。
要获得完整的配置文件集,您需要在应用程序中使用所有代码路径。具有100%覆盖率的测试套件可以解决问题,但实际上,测试套件永远不会测试所有路径。因此,也可能需要手动修改这些配置文件。
Spring和GraalVM本机映像
从Spring Framework 5.1 开始,提供了对GraalVM本机映像的初始支持。 5.2开发周期的重点是改进集成和全面支持,而不需要额外的配置或变通办法,这是即将到来的Spring Framework 5.3发行版的主题之一。
在spring-graal-nativeGithub上库展示了如何从Spring启动应用程序构建本地镜像的例子。该项目实施了GraalFeature,在配置反射,代理等方面承担了繁重的工作。
看看Spring Boot带有Tomcat的Spring MVC示例:请记住,在撰写本文时,该示例期望您正在使用GraalVM 19.2.1,并且已native-image安装插件。在构建示例之前,我们需要编译Spring Graal Feature。github存储库的根目录具有一个bash脚本来执行此操作。
$ ./build-feature.sh
完成后,让我们转到Spring MVC example文件夹并执行compile.sh。它使用Maven构建Spring应用程序,然后生成GraalVM本机映像。该native-image命令随Spring Graal功能部件的位置以及各种配置文件一起提供。请注意,本机映像生成比常规Maven构建花费的时间要长得多。另外,该进程喜欢使用大量RAM。完成后,导航到该target文件夹并启动应用程序
$ ./springmvc-tomcat
. ____ _ __ _ _
/\ / ' __ _ () __ __ _ \ \ \
( ( )__ | '_ | '| | ' / ` | \ \ \
\/ )| |)| | | | | || (| | ) ) ) )
' || .__|| ||| |__, | / / / /
=|_|======|/=////
:: Spring Boot ::
...
INFO: Started TomcatApplication in 0.054 seconds (JVM running for 0.057)
注意0.054秒的快速启动时间。为了进行比较,在JVM中运行应用程序时,报告的启动时间为1.455秒。
总结
GraalVM本机映像使我们能够构建提前编译的JVM应用程序,这些应用程序启动速度非常快,并且使用的内存更少。这对于短暂的过程绝对是有用的,尤其是在无服务器的情况下(按毫秒计费)。
由于类路径扫描和自动配置,Spring Boot应用程序在启动期间非常占用CPU。当在共享主机上同时启动多个Spring Boot应用程序时,它们开始争夺CPU,启动时间增加。编排工具甚至可能终止进程,因为它们启动得不够快。快速启动的提前编译的Spring Boot应用程序可能是该问题的答案。
容器化的Spring Boot应用程序也会有所收获。由于本机二进制文件具有所需的一切,因此不再需要将JRE烘焙到容器中。我们可以构建较小的Docker映像。
一些以微服务为重点的框架已经利用了本机图像功能(例如Quarkus,Micronaut,Helidon)。尽管Spring Boot尚未完全支持本机映像生成,但我认为它将是该框架的重要补充。
原文地址:
https://blog.indrek.io/articles/running-spring-boot-apps-as-graalvm-native-images/
译文:在GraalVM中部署运行Spring Boot应用的更多相关文章
- 【docker-compose】使用docker-compose部署运行spring boot+mysql 【处理容器的时区问题】【详解】【福利:使用docker-compose构建 wordpress+mysql】
==================================================================================================== ...
- 运行 Spring Boot 应用的 3 种方式
今天介绍 3 种运行 Spring Boot 应用的方式,看大家用过几种? 你所需具备的基础 什么是 Spring Boot? Spring Boot 核心配置文件详解 Spring Boot 开启的 ...
- 用 gradle 运行 spring boot 项目
用 gradle 运行 spring boot 项目(网页中的第6章:https://docs.spring.io/spring-boot/docs/2.1.1.RELEASE/gradle-plug ...
- 如何在自定义端口上运行 Spring Boot 应用程序?
为了在自定义端口上运行 Spring Boot 应用程序,您可以在 application.properties 中指定端口. server.port = 8090
- 使用IDEA 中 实现springboot 热部署 (spring boot devtools版)
第一步:添加springboot的配置文件 首先我先贴出我的配置 添加依赖包 <!-- spring boot devtools 依赖包. --> <dependency> & ...
- 在Docker容器中运行Spring Boot的jar包 jar外的配置文件无法生效
Spring Boot加载配置文件,默认会从几个固定位置搜索一下看看有没有配置文件 ——application.properties或者bootstrap.properties(如果你使用了sprin ...
- 如何运行Spring Boot项目
背景 帮别人指导一个Spring Boot项目,它在本地把项目push到git服务器上,然后在部署的服务器上把代码pull下来(我猜应该是这个流程) 然后他问我这项目怎么运行? 我当时就懵了,因为我平 ...
- liunx从0开始部署vue+spring boot项目(包含:安装jdk、mysql、nginx)
单纯记录,若有不合理不规范的地方请忽略. 0.配置JDK 0.下载liunx的jdk解压到/usr/local目录下. tar -xzvf jdk-8u291-linux-x64.tar.gz -C ...
- Spring Boot 框架学习 (一)配置并运行Spring Boot 框架
下载开发工具: 下载完成打开以后,第一步检查环境 查看jdk是否配置: 接着一定要注意,maven通常情况下它是没有给你配置的,要自行配置: 右键新建: 然后依赖选择web.跟Mybatis就行了. ...
随机推荐
- 详解 通道 (Channel 接口)
在本篇博文中,本人主要讲解NIO 的两个核心点 -- 缓冲区(Buffer) 和 通道 (Channel)之一的 缓冲区(Buffer), 有关NIO流的其他知识点请观看本人博文<详解 NIO流 ...
- API联调神器PostMan使用详解
简介 创建 + 测试:创建和发送任何的HTTP请求,请求可以保存到历史中再次执行 Organize:使用Postman Collections为更有效的测试及集成工作流管理和组织APIs docume ...
- 树莓派4b 上手三板斧
树莓派4b 上手三板斧 1.无屏幕和网线连接准备 windows / mac 电脑下载安装Notepad++ 新建文件并保存为ssh(该文件为空文件) 新建文件wpa_supplicant.conf ...
- 浏览器插件之王-Tampermonkey(油猴脚本)
大家电脑都在使用浏览器,相信大家对浏览器插件也不陌生,浏览器插件是安装在浏览器里面,对浏览器功能进行拓展的脚本,现在的主流浏览器都有各种各样的插件如图: 这些插件让我们的上网方便了许多,有去广告的插件 ...
- Java多台中成员访问特点
多态中的成员访问特点: A:成员变量 编译看左边,运行看左边 B:构造方法 创建子类对象的时候,访问父类的构造方法,对父类的数据进行初始化 C:成员方法 编译看左边,运行看右边.//因为调用对象时,子 ...
- python os模块判断文件是否存在
import os os.path.exists(test_file.txt)
- Java 多线程实现方式三:实现 Callable 接口
完整套路 java 通过实现Callable 接口来实现多线程相比较于继承Thread 接口和 实现Runnable 接口比较麻烦,但好处是可以有返回值. 基本套路: 1. 创建目标对象 2. 创建执 ...
- Java 自动拆箱 装箱 包装类的缓存问题--结合源码分析
都0202 了 java 1.8 已经是主流 自动装箱 .拆箱已经很普遍使用了,那么有时候是不是会遇到坑呢? 我们先来看一段代码: public class TestWraperClass { pub ...
- 2019-2020-1 20199328《Linux内核原理与分析》第九周作业
笔记部分 2019/11/12 14:45:44 从CPU和内存的角度看linux系统的运行 CPU角度:首先我们进行了系统调度,然后系统进入内核态,把信息压栈,然后我们进行进程管理,由于进入系统调用 ...
- tx-Lcn 分布式事务
测试内容 SpringCloud 微服务,有两个服务,从资料服务调度到文件服务,优先在文件服务那边 save 文件后,然后拿到 fileId 存储在资料服务中.两者之间的调用使用 feign.这期间涉 ...