”工欲善其事,必先利其器。“—孔子《论语.录灵公》
首页 > 编程 > 使用 Quarkus 和 GraalVM 本机映像增强 Java 微服务

使用 Quarkus 和 GraalVM 本机映像增强 Java 微服务

发布于2024-09-03
浏览:209

在现代软件开发的动态格局中,微服务已成为最受欢迎的架构方法。虽然这种方法提供了许多优点,但它也并非没有挑战。传统的基于 JVM 的服务经常会出现内存占用过大、启动时间过长以及 CPU 使用率过高等问题。这些挑战不仅影响技术方面,还会产生财务影响,从而显着影响运行和维护软件解决方案的总体成本。

什么是 GraalVM 本机映像?

GraalVM Native Image 是 GraalVM 的一个关键特性,它是一个高性能运行时,提供对各种编程语言和执行模式的支持。具体来说,GraalVM Native Image 允许您提前将 Java 应用程序编译为独立的本机可执行文件,从而在运行时无需使用 Java 虚拟机 (JVM)。与传统的 JVM 相比,这种创新方法生成的可执行文件表现出几乎瞬时的启动时间并显着减少了内存消耗。这些本机可执行文件经过精心制作,仅包含应用程序功能所必需的基本类、方法和依赖库。除了技术实力之外,GraalVM Native Image 还成为具有深远影响的战略解决方案。它不仅克服了技术挑战,还引入了令人信服的财务案例。通过促进高效、安全且可即时扩展的云原生 Java 应用程序的开发,GraalVM 在优化资源利用率和提高成本效益方面发挥了重要作用。从本质上讲,它在提高当代动态环境中软件解决方案的性能和财务效率方面发挥着关键作用。

技术挑战和财务影响

1。大内存占用

技术影响
由于类加载和加载类的元数据,传统的基于 JVM 的服务通常会产生大量内存开销。


财务案例
高内存消耗意味着基础设施成本增加。 GraalVM 消除了加载类的元数据和其他优化,可以更有效地利用资源,从而节省潜在的成本。

2.延长开始时间

技术影响
微服务中的冷启动可能会导致响应时间更长,影响用户体验并可能导致服务降级。


财务案例
延长启动时间不仅会影响用户满意度,还会导致更高的运营成本。 GraalVM 的优化,例如消除类加载开销和在构建过程中预生成映像堆,大大减少了启动时间,有可能最大限度地减少运营费用。

3. CPU 使用率高

技术影响
传统 JVM 通常会在启动期间消耗 CPU 周期来进行分析和即时 (JIT) 编译。


财务案例
CPU 使用率过高会导致云基础设施成本增加。 GraalVM 避免了分析和 JIT 开销,直接有助于减少 CPU 消耗,从而转化为云使用中潜在的成本节省。

解决冷启动问题

微服务,特别是在无服务器或容器化环境中,经常面临冷启动问题,影响响应时间和用户体验。 GraalVM 通过实施多项优化来应对这一挑战:

1。无类加载开销

传统的Java应用程序依靠运行时的类加载来动态加载和链接类。此过程会带来开销,特别是在启动阶段。 GraalVM 通过称为静态或提前 (AOT) 编译的过程最大限度地减少了这种开销。这涉及预加载、链接和部分启动应用程序所需的所有类。因此,在应用程序启动期间不需要运行时类加载。

2.消除解释代码

传统的 Java 虚拟机在应用即时 (JIT) 编译之前依赖于解释执行模式。这可能会导致启动延迟和 CPU 使用率增加。本机可执行文件不包含解释代码,进一步缩短了启动时间。

3.没有分析和 JIT 开销

GraalVM 无​​需启动即时 (JIT) 编译器,减少启动期间的 CPU 使用率。

4。构建时生成图像堆

GraalVM 的本机映像实用程序支持在构建过程中执行特定类的初始化过程。这会生成包含预初始化部分的映像堆,从而加快应用程序的启动速度。

Oracle GraalVM 的本机映像实用程序已证明启动时间比传统的基于 JVM 的应用程序快了近 100 倍。下图说明了运行时内存需求的大幅减少,展示了 GraalVM 与 HotSpot 相比的效率(图 1)。

Turbocharge Java Microservices with Quarkus and GraalVM Native Image

图 1 – 本机可执行文件几乎立即启动(oracle.com)


实现更精简的内存占用

GraalVM 通过以下优化有助于降低内存占用:

1。加载类没有元数据

GraalVM 避免在非堆内存中存储动态加载类的元数据。在构建过程中,会预先加载和链接必要的类信息,从而最大程度地减少运行时对其他元数据的需求。

2.无分析数据或 JIT 优化

由于字节码已经在本机代码中,GraalVM 无​​需收集分析数据以进行 JIT 优化,从而减少内存开销。

3.隔离技术

GraalVM 引入了 Isolates,这是一种将堆划分为更小、独立“堆”的技术,从而提高效率,特别是在请求处理场景中。

通常,与在 JVM 上运行相比,它消耗的内存最多减少 5 倍(图 2

Turbocharge Java Microservices with Quarkus and GraalVM Native Image

图 2 – 与 Go 或 Java HotSpot(oracle.com) 相比的本机可执行文件内存


总之,GraalVM 的本机映像实用程序为微服务带来的挑战提供了变革性的解决方案,解决了启动时间、内存占用和 CPU 使用问题。通过采用GraalVM,开发人员可以创建云原生Java应用程序,这些应用程序不仅高效、安全,而且还提供卓越的用户体验。

带有 Quarkus 的原生 Java

要将 Quarkus 服务编译为本机映像,可以使用多种方法。虽然本文不会深入探讨 Quarkus 原生构建过程,但它确实提供了基本步骤的概述。

在继续使用任何方法构建本机映像之前,在 pom.xml 文件中设置正确的本机配置文件至关重要。添加以下配置文件:

nativenative

使用已安装的 GraalVM 生成本机可执行文件

使用以下命令检查您的 GraalVM 版本:

./gu info native-image

此命令将显示已安装的 GraalVM 版本:

Downloading: Component catalog from www.graalvm.org
Filename : https://github.com/graalvm/graalvm-ce-builds/releases/download/vm-22.3.0/native-image-installable-svm-java19-linux-amd64-22.3.0.jar
Name     : Native Image
ID       : native-image
Version  : 22.3.0
GraalVM  : 22.3.0
Stability: Experimental
Component bundle native-image cannot be installed
        - The same component Native Image (org.graalvm.native-image[22.3.0.0/55b341ca1bca5219aafa8ed7c8a2273b81d184dd600d8261c837fc32d2dedae5]) is already installed in version 22.3.0

要创建本机可执行文件,请使用:

./mvnw install -Dnative

这些命令在目标目录中生成一个 *-runner 二进制文件,允许您运行本机可执行文件:

./target/*-runner

在未安装 GraalVM 的情况下创建本机可执行文件

如果在本地安装 GraalVM 存在挑战,可以使用容器内构建:

./mvnw install -Dnative -Dquarkus.native.container-build=true -Dquarkus.native.builder-image=graalvm

此命令启动 Docker 容器内的构建并提供必要的映像文件。然后您可以使用以下命令启动应用程序:

./target/*-runner

在构建本机镜像具有挑战性的情况下,RedHat 团队提供了专门为 Quarkus 框架设计的 GraalVM 发行版,称为 Mandrel。心轴流线型
GraalVM,仅专注于 Quarkus 应用程序必需的本机映像功能。要使用 Mandrel,请按照下列步骤操作:

  1. 确定适当的 Mandrel 版本 Mandrel 存储库

  2. 在 application.properties 文件中设置 Mandrel 版本:

quarkus.native.builder-image=quay.io/quarkus/ubi-quarkus-mandrel-builder-image:23.0.1.2-Final-java17

3.运行Maven构建命令:

./mvnw clean install -Pnative

手动创建容器

对于那些喜欢手动控制容器创建的人,可以采用多阶段 Docker 构建。

FROM quay.io/quarkus/ubi-quarkus-mandrel-builder-image:23.0.1.2-Final-java17 AS build
COPY --chown=quarkus:quarkus mvnw /app/mvnw
COPY --chown=quarkus:quarkus .mvn /app/.mvn
COPY --chown=quarkus:quarkus pom.xml /app/
USER quarkus
WORKDIR /app
RUN ./mvnw -B org.apache.maven.plugins:maven-dependency-plugin:3.6.1:go-offline
COPY src /app/src
RUN ./mvnw package -Dnative

FROM quay.io/quarkus/quarkus-micro-image:2.0
WORKDIR /app/
COPY --from=build /app/target/*-runner /app/application

RUN chmod 775 /app /app/application \
  && chown -R 1001 /app \
  && chmod -R "g rwX" /app \
  && chown -R 1001:root /app

EXPOSE 8080
USER 1001

CMD ["./application", "-Dquarkus.http.host=0.0.0.0"]

此 Dockerfile 协调多阶段构建,从而生成包含 Quarkus 应用程序的 Docker 映像。执行此 Dockerfile 以生成 Docker 映像,准备好运行您的 Quarkus 应用程序。

概括

GraalVM Native Image 是一项强大的技术,可以彻底改变您开发和部署 Java 微服务的方式。通过采用 GraalVM Native Image,您可以创建微服务:

  • 快点
  • 更具可扩展性
  • 部署更简单
  • 性价比更高

GraalVM Native Image 是云原生 Java 开发的关键推动者,可以帮助您实现业务所需的性能、可扩展性和成本节约。

版本声明 本文转载于:https://dev.to/yanev/turbocharge-java-microservices-with-quarkus-and-graalvm-native-image-2cb4?1如有侵犯,请联系[email protected]删除
最新教程 更多>
  • 在 Go 中使用 WebSocket 进行实时通信
    在 Go 中使用 WebSocket 进行实时通信
    构建需要实时更新的应用程序(例如聊天应用程序、实时通知或协作工具)需要一种比传统 HTTP 更快、更具交互性的通信方法。这就是 WebSockets 发挥作用的地方!今天,我们将探讨如何在 Go 中使用 WebSocket,以便您可以向应用程序添加实时功能。 在这篇文章中,我们将介绍: WebSoc...
    编程 发布于2024-11-06
  • 如何在 Python 中使用代理运行 Selenium Webdriver?
    如何在 Python 中使用代理运行 Selenium Webdriver?
    使用 Python 中的代理运行 Selenium Webdriver当您尝试将 Selenium Webdriver 脚本导出为 Python 脚本并从命令行执行时,可能会遇到在使用代理的情况下出现错误。本文旨在解决此问题,提供一种使用代理有效运行脚本的解决方案。代理集成要使用代理运行 Selen...
    编程 发布于2024-11-06
  • || 什么时候运算符充当 JavaScript 中的默认运算符?
    || 什么时候运算符充当 JavaScript 中的默认运算符?
    理解 || 的目的JavaScript 中非布尔操作数的运算符在 JavaScript 中,||运算符通常称为逻辑 OR 运算符,通常用于计算布尔表达式。但是,您可能会遇到 || 的情况。运算符与非布尔值一起使用。在这种情况下,||运算符的行为类似于“默认”运算符。它不返回布尔值,而是根据某些规则返...
    编程 发布于2024-11-06
  • 探索 Java 23 的新特性
    探索 Java 23 的新特性
    亲爱的开发者、编程爱好者和学习者, Java 开发工具包 (JDK) 23 已正式发布(2024/09/17 正式发布),标志着 Java 编程语言发展的又一个重要里程碑。此最新更新引入了大量令人兴奋的功能和增强功能,旨在改善开发人员体验、性能和模块化。 在本文中,我将分享 JDK 23 的一些主要...
    编程 发布于2024-11-06
  • ES6 数组解构:为什么它没有按预期工作?
    ES6 数组解构:为什么它没有按预期工作?
    ES6 数组解构:不可预见的行为在 ES6 中,数组的解构赋值可能会导致意外的结果,让程序员感到困惑。下面的代码说明了一个这样的实例:let a, b, c [a, b] = ['A', 'B'] [b, c] = ['BB', 'C'] console.log(`a=${a} b=${b} c=$...
    编程 发布于2024-11-06
  • 如何调整图像大小以适合浏览器窗口而不变形?
    如何调整图像大小以适合浏览器窗口而不变形?
    调整图像大小以适应浏览器窗口而不失真调整图像大小以适应浏览器窗口是一项看似简单的解决方案的常见任务。然而,遵守特定要求(例如保留比例和避免裁剪)可能会带来挑战。没有滚动条和 Javascript 的解决方案(仅限 CSS)<html> <head> <style&g...
    编程 发布于2024-11-06
  • 面向对象 - Java 中的方法
    面向对象 - Java 中的方法
    在Java中的面向对象编程中,方法在定义类和对象的行为中起着至关重要的作用。它们允许您执行操作、操纵数据以及与其他对象交互。它们允许您执行操作、操纵数据以及与其他对象交互。在本文中,我们将探讨 Java 中的方法、它们的特性以及如何有效地使用它们。 什么是方法? 方法是类中定义对象行...
    编程 发布于2024-11-06
  • 如何使用 MAMP 修复 Mac 上 Laravel 迁移中的“没有这样的文件或目录”错误?
    如何使用 MAMP 修复 Mac 上 Laravel 迁移中的“没有这样的文件或目录”错误?
    解决 Mac 上 Laravel 迁移中的“没有这样的文件或目录”错误简介:当尝试在 Mac 上的 Laravel 项目中运行“php artisan migrate”命令时,用户经常会遇到找不到文件或目录的错误。这个令人沮丧的问题可能会阻碍迁移过程并阻止开发人员在项目中取得进展。在本文中,我们将深...
    编程 发布于2024-11-06
  • SOLID 原则使用一些有趣的类比与车辆示例
    SOLID 原则使用一些有趣的类比与车辆示例
    SOLID 是计算机编程中五个良好原则(规则)的缩写。 SOLID 允许程序员编写更易于理解和稍后更改的代码。 SOLID 通常与使用面向对象设计的系统一起使用。 让我们使用车辆示例来解释 SOLID 原理。想象一下,我们正在设计一个系统来管理不同类型的车辆,例如汽车和电动汽车,...
    编程 发布于2024-11-06
  • 如何从另一个异步函数中的异步函数返回解析值?
    如何从另一个异步函数中的异步函数返回解析值?
    如何从异步函数返回一个值?在提供的代码中,init()方法返回一个Promise,但是getPostById() 方法尝试直接访问 Promise 返回的值。为了解决这个问题,需要修改 init() 方法,使其在 Promise 解析后返回 getPostById() 的值。更新后的代码如下:cla...
    编程 发布于2024-11-06
  • 了解如何使用 React 构建多人国际象棋游戏
    了解如何使用 React 构建多人国际象棋游戏
    Hello and welcome! ?? Today I bring a tutorial to guide you through building a multiplayer chess game using SuperViz. Multiplayer games require real-t...
    编程 发布于2024-11-06
  • 如何使用 JavaScript 正则表达式验证 DD/MM/YYYY 格式的日期?
    如何使用 JavaScript 正则表达式验证 DD/MM/YYYY 格式的日期?
    使用 JavaScript 正则表达式验证 DD/MM/YYYY 格式的日期验证日期是编程中的常见任务,并且能够确保日期采用特定格式至关重要。在 JavaScript 中,正则表达式提供了执行此类验证的强大工具。考虑用于验证 YYYY-MM-DD 格式日期的正则表达式模式:/^\d{4}[\/\-]...
    编程 发布于2024-11-06
  • JavaScript 中的节流和去抖:初学者指南
    JavaScript 中的节流和去抖:初学者指南
    使用 JavaScript 时,过多的事件触发器可能会降低应用程序的速度。例如,用户调整浏览器窗口大小或在搜索栏中输入内容可能会导致事件在短时间内重复触发,从而影响应用程序性能。 这就是节流和去抖可以发挥作用的地方。它们可以帮助您管理在处理过于频繁触发的事件时调用函数的频率。 ?什么...
    编程 发布于2024-11-06
  • 在 Go 中导入私有 Bitbucket 存储库时如何解决 403 Forbidden 错误?
    在 Go 中导入私有 Bitbucket 存储库时如何解决 403 Forbidden 错误?
    Go 从私有 Bitbucket 存储库导入问题排查(403 禁止)使用 go get 命令从 Bitbucket.org 导入私有存储库可能会遇到 403 Forbidden 错误。要解决此问题,请按照以下步骤操作:1.建立 SSH 连接:确保您已设置 SSH 密钥并且能够使用 SSH 连接到 B...
    编程 发布于2024-11-06
  • Singleton 和原型 Spring Bean 范围:详细探索
    Singleton 和原型 Spring Bean 范围:详细探索
    当我第一次开始使用 Spring 时,最让我感兴趣的概念之一是 bean 范围的想法。 Spring 提供了各种 bean 作用域,用于确定在 Spring 容器内创建的 bean 的生命周期。最常用的两个范围是 Singleton 和 Prototype。了解这些范围对于设计高效且有效的 Spri...
    编程 发布于2024-11-06

免责声明: 提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发到邮箱:[email protected] 我们会第一时间内为您处理。

Copyright© 2022 湘ICP备2022001581号-3