SpringBoot: 使用GraalVM编译native应用

曾今Go语言里让我最艳羡的两个特性,一个是Goroutine,一个是native编译。 Java 21的虚线程实现了类似Goroutine的能力。Spring Boot 3.x开始提供了GraalVM的支持,现在Spring Boot也能打包成native文件了。

这一篇文章的目标是用一个案例讲解如何将Spring Boot应用打包成native文件。整个过程主要是4步:

  1. 环境准备,讲解怎么安装GraalVM,安装本地编译器(gcc,cl)
  2. 测试工程,创建一个极简的Spring Boot应用,只有个Controller
  3. 编译打包,使用GraalVM、Maven将Spring Boot应用构建成可执行文件
  4. 测试运行,执行生成的可执行文件,访问Controller看是否正常

1. 环境准备

1. 前置条件

GraalVM依赖一些本地工具才能完成工作,这些工具包括:

  • C的头文件
  • glibc-devel
  • zlib
  • gcc
  • libstdc++-static

不同的操作系统,采用的安装方式不同,在Linux下可以使用包管理工具安装,比如yum、apt等

Linux

yum install gcc glibc-devel zlib-devel
apt-get install build-essential libz-dev zlib1g-dev

Windows

Windows可以通过安装Visual Studio完成依赖包安装

  1. 安装Visual Studio Build Tools
  2. 安装Visual Studio
2. 安装GraalVM

从官网选择Java版本、平台来下载,下载的zip包解压即安装,接下来只要设置环境变量JAVA_HOME、PATH即可

  • 设置GRAALVM_HOME为解压文件夹的根目录
  • 设置PATH为解压文件夹下的bin
3. 验证安装

通过执行native-image --help,确认我们安装成功

4. 参考资料

关于GraalVM的安装过程,可以参考官方的Get Started文档: Getting Started with GraalVM

2. 测试工程

1. 创建工程

使用mvn archetype:generate根据archetype maven-archetype-quickstart生成一个最简单的Java项目。

mvn archetype:generate -DarchetypeGroupId=org.apache.maven.archetypes 
    -DarchetypeArtifactId=maven-archetype-quickstart 
    -DarchetypeVersion=1.4 
    -DgroupId=com.keyniu.dis 
    -DartifactId=DiveInSpring 
    -Dversion=0.1 
    -Dpackage=com.keyniu.dis 
    -DinteractiveMode=false
2. 添加Spring Boot支持

修改pom.xml选择spring-boot-starter-parent作为parent,添加native-maven-plugin插件

<?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">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.keyniu.dis</groupId>
    <artifactId>DiveInSpring</artifactId>
    <version>0.1</version>
    <name>DiveInSpring</name>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.3.0</version>
    </parent>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>17</maven.compiler.source>
        <maven.compiler.target>17</maven.compiler.target>
    </properties>

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

    <build>
        <plugins>
            <plugin>
                <groupId>org.graalvm.buildtools</groupId>
                <artifactId>native-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>
3. 添加测试类

写一个最简单启动引导类,提供一个最简单的接口/hello,用于后续测试。

package com.keyniu.dis;


import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@SpringBootApplication
@RestController
public class DiveInMain {

    @GetMapping("/hello")
    public String hello(@RequestParam("name") String name) {
        return "hello," + name;
    }

    public static void main(String[] args) {
        SpringApplication.run(DiveInMain.class);
    }
}

3. 编译打包

1. 命令行窗口

为了让GraalVM能引用到VisualStudio的编译工具,我选择在x64 Native Tools窗口中运行接下来的命令。

在执行命令之前,确保你的环境变量设置正确,有添加GraalVM相关的配置

set GRAALVM_HOME=D:\Programs\GraalVM
set PATH=D:\Programs\GraalVM\bin;%PATH%
2. 进行native编译

在工程的根目录下执行mvn -Pnative native:compile,进行编译,最后会生成一个exe到工程的target目录下,输入如下

D:\Workspace\DiveInSpring>mvn -Pnative native:compile
...
Produced artifacts:
 D:\Workspace\DiveInSpring\target\DiveInSpring.exe (executable)

4. 测试运行

只需要在命令行里输入DiveInSpring.exe执行,可以看到只需要0.063s就能完成启动,这个项目如果通过java -jar启动的话大概耗时0.97s,还是快了很多的。打包后的exe文件大小是80M。

通过curl命令验证,接口正常提供服务

5. 使用建议

可以看到整个构建过程已经相当的顺畅,从可执行文件的大小,启动时间,内存占用都于明显的提升,应该说Spring + GraalVM离成熟应用已经不远了。由于GraalVM使用了Closed World Optimization,实际上这个可执行程序还是有一些限制的,主要是:

  1. Class初始化,有些初始化会在build期间完成,可以参考GraalVM文档: Class Initialization in Native Image
  2. 反射和动态代理,需要的编译期间完成
  3. 不支持JNI,如果有本地方法调用需要根据GraalVM提供的接口定制实现
  4. 执行时无法访问字节码,正常的debug、监控等用JVM TI实现的功能都不再可用

在SpringBoot中, 像profiles、 条件配置、 @Enable*等功能会受到影响,而其实这些特性正在被广泛使用,这些限制在完全解决之前实际使用还是有障碍的。关于可以执行文件的DEBUG、监控在GraalVM官网都已经有对应的文档,但是将它和公司内部的监控报警做集成还有一段路要走,已经看到黎明的曙光了。

A. 参考资料

  1. GraalVM构建Swing应用
  2. 使用GDB Debug由GraalVM构建的程序,Debug Native Executables with GDB
  3. 让可执行文件支持JFR,Build and Run Native Executables with JFR
  4. 手动创建Spring Boot工程

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/680898.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

ATA-7015增材制造测试高压放大器的应用场景介绍

微纳3D打印技术是一种结合了微纳米制造和3D打印的先进制造技术。它能够在微米甚至纳米级别上&#xff0c;将复杂的3D结构精确地打印出来。这种技术的出现&#xff0c;使得我们可以在一个微观的世界里&#xff0c;以难以置信的精度和效率&#xff0c;进行各种材料的制造和加工。…

#02 安装指南:如何配置Stable Diffusion环境

文章目录 前言前置条件第1步&#xff1a;安装Python和PIP第2步&#xff1a;创建虚拟环境第3步&#xff1a;安装PyTorch和CUDA第4步&#xff1a;安装Stable Diffusion相关库第5步&#xff1a;测试环境结论 前言 在之前的文章中&#xff0c;我们介绍了Stable Diffusion基础入门和…

【Python】 探索Python单元测试:运行unittest测试用例

基本原理 单元测试是软件开发过程中的一个重要环节&#xff0c;它可以帮助开发者确保每个单独的组件或模块都能按预期工作。在Python中&#xff0c;unittest是一个内置的测试框架&#xff0c;它提供了丰富的功能来支持自动化测试。 unittest测试框架的核心是测试用例&#xf…

2024第26届大湾区国际电机博览会暨发展论坛

2024第二十六届大湾区国际电机博览会 暨发展论坛 2024第26届大湾区国际电机博览会暨发展论坛 The 26th Greater Bay Area International Motor Expo and Development Forum 时间&#xff1a;2024年12月4-6日 地址&#xff1a;深圳国际会展中心&#xff08;宝安新馆&#x…

【计算机网络】对应用层HTTP协议的重点知识的总结

˃͈꒵˂͈꒱ write in front ꒰˃͈꒵˂͈꒱ ʕ̯•͡˔•̯᷅ʔ大家好&#xff0c;我是xiaoxie.希望你看完之后,有不足之处请多多谅解&#xff0c;让我们一起共同进步૮₍❀ᴗ͈ . ᴗ͈ აxiaoxieʕ̯•͡˔•̯᷅ʔ—CSDN博客 本文由xiaoxieʕ̯•͡˔•̯᷅ʔ 原创 CSDN 如…

java代码审计之fastjson反序列化漏洞

fastjson反序列化漏洞分析 Fastjson 是一个 Java 库&#xff0c;可以将 Java 对象转换为 JSON 格式&#xff0c;当然它也可以将 JSON 字符串转换为 Java 对象。Fastjson 可以操作任何 Java 对象&#xff0c;即使是一些预先存在的没有源码的对象。该产品主要提供了两个接口&…

nginx与busybox离线镜像安装包

目录 概述实践离线资源nginxbusybox加载上传harbor 概述 nginx与busybox离线镜像安装包制作。如有疑问&#xff0c;详细请参考 docker镜像的导入导出 实践 离线资源 如果懒得弄&#xff0c;请至此下载 nginx、busybox (2024-06-04相对今天是最新版本) nginx 先找一台装有 d…

【知识点小结】目标检测深度学习算法网络训练时的一些注意事项

验证模型的batch size如何设置&#xff1f; 若输入模型数据shape固定&#xff0c;验证时对batch size无限制若输入模型数据shape不固定&#xff0c;验证时将batch size设置成1 训练模型需要提前热身&#xff1f;&#xff08;Warm-up&#xff09; 主要为了解决初始学习率过大…

短期业绩波动较大被券商不予评级,金种子酒背靠华润如何发力?

《港湾商业观察》施子夫 王璐 虽然一季度成功实现了扭亏为盈&#xff0c;但从近些年年报来看&#xff0c;金种子酒&#xff08;600199.SH&#xff09;的业绩压力依然不容小觑。白酒主业萎靡不振时&#xff0c;金种子酒开始了剥离非主营业务。 这些措施能否有利于主业向好&am…

yolov5的口罩识别系统+GUI界面 (附代码)

基于YOLOv5模型的口罩识别系统&#xff0c;结合了GUI界面&#xff0c;旨在帮助用户快速、准确地识别图像或视频中佩戴口罩的情况。YOLOv5是一种流行的目标检测模型&#xff0c;具有高效的实时检测能力&#xff0c;而GUI界面则提供了友好的用户交互界面&#xff0c;使得整个系统…

计算机网络 —— 数据链路层(VLAN)

计算机网络 —— 数据链路层&#xff08;VLAN&#xff09; 什么是VLAN为什么要有VLANVLAN如何实现IEEE 802.1Q 我们今天来看VLAN&#xff1a; 什么是VLAN VLAN&#xff08;Virtual Local Area Network&#xff0c;虚拟局域网&#xff09;是一种网络技术&#xff0c;它将一个物…

段子照进现实!裁员裁到大动脉,理想被传召回被裁员工…?

你一定看过类似这样的段子吧&#xff01;「公司高层换血&#xff0c;各个部门丢裁了个遍&#xff0c;终于要对财务下手&#xff0c;财务总监走之前&#xff0c;让公司补了六百万税」 还有类似这样的&#xff1a;「某公司裁员把一个销售主管裁了&#xff0c;那销售上午刚谈了个1…

Java Web学习笔记5——基础标签和样式

<!DOCTYPE html> html有很多版本&#xff0c;那我们应该告诉用户和浏览器我们现在使用的是HMTL哪个版本。 声明为HTML5文档。 字符集&#xff1a; UTF-8&#xff1a;现在最常用的字符编码方式。 GB2312&#xff1a;简体中文 BIG5&#xff1a;繁体中文、港澳台等方式…

【第三节】C/C++数据结构之栈与队列

目录 一、数据结构-栈 1.1 栈的定义 1.2 栈的 ADT (Abstract Data Type) 1.3 栈的顺序存储结构及实现 二、数据结构-队列 2.1 队列的定义 2.2 队列的 ADT 2.3 队列的顺序存储结构与实现 2.4 优先队列 2.5 各种队列异同点 一、数据结构-栈 1.1 栈的定义 栈(Stack)可…

硬件高效的线性注意力机制Gated Linear Attention论文阅读

0x0. 前言 上篇文章 flash-linear-attention中的Chunkwise并行算法的理解 根据GLA Transformer Paper&#xff08;https://arxiv.org/pdf/2312.06635 作者是这位大佬 sonta&#xff09;通过对Linear Attention的完全并行和RNN以及Chunkwise形式的介绍理解了Linear Attention的…

精酿啤酒新风尚,FENDI CLUB盛宴启幕,品质生活触手可及

随着现代人对生活品质的追求日益提升&#xff0c;精酿啤酒作为一种新兴的生活方式&#xff0c;正逐渐引领潮流。在这个背景下&#xff0c;FENDI CLUB的盛宴盛大开启&#xff0c;为广大消费者带来了一场别具一格的品质生活体验。 一、精酿啤酒的崛起 精酿啤酒以其独特的口感、…

vscode 搜索框乱码

vscode 搜索文件夹 搜索txt文件 ignore取消 搜索中文乱码 https://zhuanlan.zhihu.com/p/661347670 文件 -》首选项-》设置 搜索encoding -》设置 simpified chinese 中文插件

HTML5+CSS3+JS小实例:网格图库

实例:网格图库 技术栈:HTML+CSS+JS 效果: 源码: 【HTML】 <!DOCTYPE html> <html lang="zh-CN"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0&…

深入浅出mysql海量数据批量更新插入、批量查询

1. mysql的批量写 mysql 批量插入可以用下面这种&#xff0c;在values 之后跟上各种多个值列表。但这种写法可能导致sql长度超长、锁超时等问题。 insert into (field1,field1,field1,) values (value01,value02,value03),(value11,value12,value13),(value21,value22,value2…

LLM推理加速原理(一)

1.大语言模型的基本结构 transfomer block: 输入--->正则化-->qkv三个矩阵层(映射到三个不同空间中)---->q,k,v之后self attention进行三0合一---->线性映射,正则化。 2.大语言模型的推理 目前主流的语言大模型都采用decoder-only的结构,其推理过程由两部分…