SpringBoot项目GraalVM迁移

news/2024/10/2 18:22:39

一些背景

一直想把项目迁移到使用GraalVM构建出的原生应用上,但是在前段时间的一次尝试后,发现很难做到,其中一个最主要原因就在于我目前手头上没有X86架构的电脑。平时我使用的是一个M1处理器的MacBook,编译出的Docker镜像架构指令集也是Arm64的,无法在我的X86服务器启动。原本想着就这样算了,但是实际上我最近在和一个朋友做一个node的项目,这个项目上朋友计划配合GitHub Action进行发布流水线的操作,我就去查了一个,没想到还真查到Graal官方推出的一个Github Action插件,基于这里,我就去尝试探索了下,发现还真可以编译成功,最终也把项目在生产环境启动起来了。但是在这个过程中踩了不少坑。

代码变更

这里代码变更主要分为3类,分别是Gradle配置,GitHub Action配置文件和手动补充一些需要被A OT进去的配置。

tasks.named<BootBuildImage>("bootBuildImage") {environment = mapOf("BP_NATIVE_IMAGE_BUILD_ARGUMENTS" to"""-march=compatibility""")docker {publish.set(true)publishRegistry {imageName.set("docker.io/mingchiuli/${rootProject.name}:${version}")url.set("https://docker.io")val un = System.getenv("DOCKER_USERNAME")val pwd = System.getenv("DOCKER_PWD")username.set(un)password.set(pwd)}}
}

基于Spring boot的初始化配置,还需要对BootBuildImage这个任务进行一定配置,因为需要使用Spring官方提供的这个打包任务进行镜像构建,故配置DockerHub的用户名和密码用来推送镜像。在这里用户名和密码是通过环境变量注入的,需要和GitHub Action配置文件搭配。配置里的-march=compatibility主要作用是禁止CPU指令优化,不加的话有可能启动镜像报错CPU指令集不支持的问题。

name: GraalVM build
on: [push, pull_request]
jobs:build:runs-on: ubuntu-lateststeps:- uses: actions/checkout@v4- uses: graalvm/setup-graalvm@v1with:java-version: '21'      # See 'Options' section below for all supported versionsdistribution: 'graalvm' # See 'Options' section below for all available distributionsgithub-token: ${{ secrets.GITHUB_TOKEN }}- name: Example steprun: |echo "GRAALVM_HOME: $GRAALVM_HOME"echo "JAVA_HOME: $JAVA_HOME"java --versionnative-image --version- name: Example step using Gradle pluginrun: ./gradlew bootBuildImageenv:DOCKER_USERNAME: ${{ secrets.DOCKERHUB_USERNAME }}DOCKER_PWD: ${{ secrets.DOCKERHUB_PWD }}

GitHub Action配置文件里对环境变量进行定义,就是项目里Gradle配置的DOCKER_USERNAME和DOCKER_PWD。这里的关键在于需要把gradle-wrapper.jar和gradle-wrapper.properties提交到GitHub仓库里,否则会报错找不到gradlew这个命令。

另外,像caffeine这样的库,可能它在程序运行的时候根据开发者缓存的配置动态加载了一些类进来,所以需要增加一些配置,如:

        hints.reflection().registerType(TypeReference.of("com.github.benmanes.caffeine.cache.SSMSA"),MemberCategory.PUBLIC_FIELDS, MemberCategory.INVOKE_DECLARED_CONSTRUCTORS, MemberCategory.INVOKE_PUBLIC_METHODS);

上线

上线我使用的是Docker Compose,关于生产环境的服务配置,只需要通过Docker容器启动的时候环境变量注入就可以了。在Docker Compose文件的environment这个下面写就OK。

之后的计划

这次成功改造为native化可以说久旱逢甘霖,由于native化以后占用内存大大降低,使在有限的经济条件下项目有了微服务化的可能,以前后端应用需要600M的内存占用,现在优化到200M:

启动时间也有了大提升,之前启动需要25秒左右,现在只需要4秒上下:

目前这个服务器内存节省出来很多内存,可以把它拆分出微服务了。之后这个项目的改造方向是应该是这个。

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

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

相关文章

董浩影评

本文来自博客园,作者:东岸,转载请注明原文链接:https://www.cnblogs.com/donghao99/p/18182035

Rust | 实现 API 限速操作 Example

在这篇文章中,我们将讨论如何在 Rust 中实现 API 限速。当涉及到生产中的服务时,是为了确保不良行为者不会滥用 API——这就是 API 限速的作用所在。 我们将实现 “滑动窗口” 算法,通过动态周期来检查请求历史,并使用基本的内存 hashmap 来存储用户 IP 及其请求时间。我们…

Tasks 和算子链

Flink中的每一个操作算子称为一个Task(任务),算子的每个具体实例则称为SubTask(子任务),SubTask是Flink中最小的处理单元,多个SubTask可能在不同的机器上执行。一个TaskManager进程包含一个或多个执行线程,用于执行SubTask。 TaskManager中的一个Task Slot对应一个执行…

MT3516W-ASEMI工业电源专用MT3516W

MT3516W-ASEMI工业电源专用MT3516W编辑:ll MT3516W-ASEMI工业电源专用MT3516W 型号:MT3516W 品牌:ASEMI 封装:MTW-5 最大重复峰值反向电压:1600V 最大正向平均整流电流(Vdss):35A 功率(Pd):大功率 芯片个数:5 引脚数量:5 类型:插件整流桥、整流方桥 正向浪涌电流:45…

会充电的CANoe-赋能新能源汽车,高效完成即插即充(PnC)智能充电功能测试

ISO 15118-2标准中描述的PnC功能,可以实现插枪即充电,识别、计费信息、充电参数都通过高级别通信在EV和EVSE之间自动交换。简化了电动汽车的充电过程,提高了用户体验,为电动汽车行业带来了更智能、更便捷的充电解决方案。然而,电动汽车和充电站之间要实现自动通信和计费,…

03 插入排序

03 插入排序1.插入排序的含义类似扑克牌,假设认为0-0位置有序,再把0-1的位置变有序,循环直到所有的有序。每次拿取右侧的数字,一个一个对比放到左侧来。2.示例代码 def insertion_sort(arr):if arr is None or len(arr) < 2:returnfor i in range(1, len(arr)):# 0 ~ i-…

IR2104详解

摘要:从NMOS到半桥驱动 关键词:NMOS、半桥、死区、自举升压目录基础知识 NMOS原理 半桥控制原理 IR2104简介 示例电路 引脚定义 电路原理详解 自举升压 死区控制 总结 链接 引入:IR2104是我上手的第一个半桥栅极驱动芯片,使用两片IR2104就可以搭建一个全桥电路控制电机的正…

电脑增加硬盘后DP线显示器没信号问题

最近遇到一个项目,电脑硬盘空间不够,客户需要增加一个4T机械硬盘。 可增加后显示器不亮了。 拔掉机械硬盘后又恢复正常。我到现场后测试确实是这样。更换机械硬盘的电源线和数据线也一样。 并且电脑实际上是启动了的,就是没有显示输出。实在是找不到原因,只能说换个高清线试…