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

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

发布于2024-11-08
浏览:131

在现代软件开发的动态格局中,微服务已成为最受欢迎的架构方法。虽然这种方法提供了许多优点,但它也并非没有挑战。传统的基于 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 文件中设置正确的本机配置文件至关重要。添加以下配置文件:


  
    native
    
      native
    
  

使用已安装的 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]删除
最新教程 更多>
  • 如何使用FormData()处理多个文件上传?
    如何使用FormData()处理多个文件上传?
    )处理多个文件输入时,通常需要处理多个文件上传时,通常是必要的。 The fd.append("fileToUpload[]", files[x]); method can be used for this purpose, allowing you to send multi...
    编程 发布于2025-04-20
  • 如何使用不同数量列的联合数据库表?
    如何使用不同数量列的联合数据库表?
    合并列数不同的表 当尝试合并列数不同的数据库表时,可能会遇到挑战。一种直接的方法是在列数较少的表中,为缺失的列追加空值。 例如,考虑两个表,表 A 和表 B,其中表 A 的列数多于表 B。为了合并这些表,同时处理表 B 中缺失的列,请按照以下步骤操作: 确定表 B 中缺失的列,并将它们添加到表的末...
    编程 发布于2025-04-20
  • Go语言垃圾回收如何处理切片内存?
    Go语言垃圾回收如何处理切片内存?
    在Go Slices中的垃圾收集:详细的分析在GO中,Slice是一个动态数组,引用了基础阵列。使用切片时,了解垃圾收集行为至关重要,以避免潜在的内存泄漏。考虑使用slice使用slice的以下实现:字符串{ R:=(*Q)[0] *q =(*q)[1:len(*q)] 返回...
    编程 发布于2025-04-20
  • 如何干净地删除匿名JavaScript事件处理程序?
    如何干净地删除匿名JavaScript事件处理程序?
    删除匿名事件侦听器将匿名事件侦听器添加到元素中会提供灵活性和简单性,但是当要删除它们时,可以构成挑战,而无需替换元素本身就可以替换一个问题。 element? element.addeventlistener(event,function(){/在这里工作/},false); 要解决此问题,请考虑...
    编程 发布于2025-04-20
  • 如何从PHP中的数组中提取随机元素?
    如何从PHP中的数组中提取随机元素?
    从阵列中的随机选择,可以轻松从数组中获取随机项目。考虑以下数组:; 从此数组中检索一个随机项目,利用array_rand( array_rand()函数从数组返回一个随机键。通过将$项目数组索引使用此键,我们可以从数组中访问一个随机元素。这种方法为选择随机项目提供了一种直接且可靠的方法。
    编程 发布于2025-04-20
  • 在所有浏览器中实现左对齐文本的斜线方法
    在所有浏览器中实现左对齐文本的斜线方法
    ] 在倾斜行上的文本对齐背景在倾斜行上实现左对齐的文本可能会构成挑战,在nectera时尤其是挑战。兼容性(返回IE9)。通过引入一系列平方元素并计算其尺寸,我们可以创建一个有效的解决方案: .loop(@i) when (@i > 0){ .loop((@i - 1...
    编程 发布于2025-04-20
  • 在UTF8 MySQL表中正确将Latin1字符转换为UTF8的方法
    在UTF8 MySQL表中正确将Latin1字符转换为UTF8的方法
    在UTF8表中将latin1字符转换为utf8 ,您遇到了一个问题,其中含义的字符(例如,“jáuòiñe”)在utf8 table tabled tablesset中被extect(例如,“致电。为了解决此问题,您正在尝试使用“ mb_convert_encoding”和“ iconv”转换受...
    编程 发布于2025-04-20
  • 您如何在Laravel Blade模板中定义变量?
    您如何在Laravel Blade模板中定义变量?
    在Laravel Blade模板中使用Elegance 在blade模板中如何分配变量对于存储以后使用的数据至关重要。在使用“ {{}}”分配变量的同时,它可能并不总是最优雅的解决方案。幸运的是,Blade通过@php Directive提供了更优雅的方法: $ old_section =“...
    编程 发布于2025-04-20
  • 为什么我会收到MySQL错误#1089:错误的前缀密钥?
    为什么我会收到MySQL错误#1089:错误的前缀密钥?
    mySQL错误#1089:错误的前缀键错误descript [#1089-不正确的前缀键在尝试在表中创建一个prefix键时会出现。前缀键旨在索引字符串列的特定前缀长度长度,可以更快地搜索这些前缀。了解prefix keys `这将在整个Movie_ID列上创建标准主键。主密钥对于唯一识别...
    编程 发布于2025-04-20
  • 在Java中使用for-to-loop和迭代器进行收集遍历之间是否存在性能差异?
    在Java中使用for-to-loop和迭代器进行收集遍历之间是否存在性能差异?
    For Each Loop vs. Iterator: Efficiency in Collection TraversalIntroductionWhen traversing a collection in Java, the choice arises between using a for-...
    编程 发布于2025-04-20
  • 在细胞编辑后,如何维护自定义的JTable细胞渲染?
    在细胞编辑后,如何维护自定义的JTable细胞渲染?
    在JTable中维护jtable单元格渲染后,在JTable中,在JTable中实现自定义单元格渲染和编辑功能可以增强用户体验。但是,至关重要的是要确保即使在编辑操作后也保留所需的格式。在设置用于格式化“价格”列的“价格”列,用户遇到的数字格式丢失的“价格”列的“价格”之后,问题在设置自定义单元格...
    编程 发布于2025-04-20
  • 为什么尽管有效代码,为什么在PHP中捕获输入?
    为什么尽管有效代码,为什么在PHP中捕获输入?
    在php ;?>" method="post">The intention is to capture the input from the text box and display it when the submit button is clicked.但是,输出...
    编程 发布于2025-04-20
  • 在JavaScript中如何并发运行异步操作并正确处理错误?
    在JavaScript中如何并发运行异步操作并正确处理错误?
    同意操作execution 在执行asynchronous操作时,相关的代码段落会遇到一个问题,当执行asynchronous操作:此实现在启动下一个操作之前依次等待每个操作的完成。要启用并发执行,需要进行修改的方法。 第一个解决方案试图通过获得每个操作的承诺来解决此问题,然后单独等待它们: co...
    编程 发布于2025-04-20
  • 图片在Chrome中为何仍有边框?`border: none;`无效解决方案
    图片在Chrome中为何仍有边框?`border: none;`无效解决方案
    在chrome 在使用Chrome and IE9中的图像时遇到的一个频繁的问题是围绕图像的持续薄薄边框,尽管指定了图像,尽管指定了;和“边境:无;”在CSS中。要解决此问题,请考虑以下方法: Chrome具有忽略“ border:none; none;”的已知错误,风格。要解决此问题,请使用以下...
    编程 发布于2025-04-20
  • 为什么不````''{margin:0; }`始终删除CSS中的最高边距?
    为什么不````''{margin:0; }`始终删除CSS中的最高边距?
    在CSS 问题:不正确的代码: 全球范围将所有余量重置为零,如提供的代码所建议的,可能会导致意外的副作用。解决特定的保证金问题是更建议的。 例如,在提供的示例中,将以下代码添加到CSS中,将解决余量问题: body H1 { 保证金顶:-40px; } 此方法更精确,避免了由全局保证金重置引...
    编程 发布于2025-04-20

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

Copyright© 2022 湘ICP备2022001581号-3