当前位置:Java -> 使用快速预热实现可持续的Java应用

使用快速预热实现可持续的Java应用

Java启动缓慢的问题在Java社区中是臭名昭著的,但其含义有时会令人困惑。缓慢启动问题与在复杂的Java框架上启动一组相互连接的应用程序相关。这个过程包括在Spring Boot中启动几个应用程序,其中每个应用程序大约需要10秒的时间。因此,作为一个整体的生产启动将需要一分钟的时间,但在这组中JVM的启动只需50毫秒。这个广泛的慢Java启动的含义并不完全正确,从技术上讲这不是一个Java问题,而是框架的问题。

缓慢启动和热身的影响是由我们使用的复杂框架和运行时的动态特性引起的。Java在其功能上是独一无二的,由于其编码和生态系统的强大,Java在企业中非常受欢迎。然而,同样的复杂性可能使其在云端表现得笨拙。

Java应用程序的启动和热身从技术上来说包括几个连续的过程:JVM启动、应用程序启动和JVM热身。在这些过程中,JVM获得额外的时间来提供应用程序的最佳性能。

热身阶段是由JVM来编译和优化代码。在大型复杂应用程序的情况下,这个过程需要为代码解释和优化而消耗更长的时间,达到几分钟。

每次启动程序时,这些过程都将重新开始。实际上,这意味着我们花费时间来运行应用程序,并使用大量的CPU和内存资源来确保其在启动点的性能。因此,缓慢的启动和热身将导致额外的资源投入到准备运行应用程序的阶段,而不是可能需要用于其操作的资源。

因此,缓慢的启动和热身会导致云成本增加和资源过度利用。

寻求解决方案

解决这个问题有几种方法。

  1. 本地映像:能够减少Java应用程序的启动时间。它使用不同的AOT编译器,通常提供更好的性能。本地映像使用“封闭世界假设”方法,在定义时其编译器会去除热身阶段。本地映像包含由运行用户定义的静态初始化器创建的代码和数据的预初始化堆。本地映像快照机制只记录核心库类和用户定义的静态初始化代码。这种方法的特定优势允许保持本地映像的部署大小不变。在考虑实现本地映像时,应当参考“本地映像兼容指南”,以确保它适用于您的特定应用程序,因为并非所有Java应用程序都能利用这种方法。
  2. 列顿项目其主要目标是“改善Java程序的启动时间、性能峰值时间和占用空间”。这个项目目前仍需要完成,因此我们无法评估其效果和可能的适应难度。然而,列顿项目旨在解决缓慢启动的问题,我们怀着很大的期待关注着相关新闻。
  3. 检查点下的协调还原这是一个完全专注于Java启动增强的OpenJDK项目。该项目的主要目标是开发一个新的标准机制不依赖于API,来通知Java程序关于检查点和还原事件。检查点下的协调还原(CRaC)提供了一个API机制解决方案,允许在任意时间点创建正在运行的应用程序的图像(“检查点”),然后从检查点文件(快照)启动图像。CRaC快照(“检查点”)包括特定时间点上HotSpot进程的整个状态。然后将应用程序的状态恢复到创建检查点的位置,继续执行。在Java运行时中使用CRaC功能还提供了在多个实例上部署特别相关的快照的选项。然而,使用CRaC来减少应用程序的需要对CI/CD环境做一些修改,并且优化检查点时机可能并不容易。
  4. Amazon Lambda这是基于CRaC技术的一个独立产品。Lambda在高可用性计算基础设施上运行您的代码并管理所有计算资源,包括服务器和操作系统的维护、容量规划、自动缩放和日志记录。Lambda对于您的开发目标可能非常便利,但与JVM相比,它也更昂贵且效果不佳。
  5. Java优化:迁移到较新的长期支持(LTS)版本的Java可能会稍微提高应用程序的性能,带来一些微小的改变。这种优化是一种快速方法,可以立即使用。

效果对您的运行时可持续性的影响

缓慢启动问题影响了您运行时的整体性能,为了使您的应用程序具有可持续性和性能,您需要使用其中一种解决方案。

在上述技术中,本地映像是Java社区中最常采用的方法,特别适用于Spring用户实现更快的应用程序启动。它已经存在了相当长的时间,可以提高性能,使程序在较少的内存中运行,并且不需要单独的JDK进行部署。

大多数框架支持GraalVM,并且迁移到GraalVM非常简单。同时,由于封闭世界假设的存在,GraalVM可能需要根据您的Java应用程序的特定情况进行个别研究,并且并不总是适合解决启动问题。

CRaC的解决方案引起了Java社区的很多期待。CRaC,就像Project Leyden一样,旨在解决缓慢启动的问题。现在您可以获取支持CRaC API的OpenJDK运行时和容器。这些解决方案已经准备好部署,并且可立即带来显著的改进。支持CRaC的OpenJDK运行时和带有CRaC支持的小型容器对Spring开发者具有很高的价值,因为Spring在2023年宣布CRaC功能支持

CRaC的主要优势在于其易用性,结合对应用程序性能和云成本的即时影响。支持协调还原检查点的Linux-based容器扩展了应用程序的性能。CRaC降低了应用程序启动时对处理器和内存的负载,减少云成本,并提高了应用程序的性能和可持续性。

我们目前还无法充分评估和测试雷登结果。该项目引入了Class Data Sharing + AOT on steroids,看起来非常有希望与Java协同合作,能够在JVM上实现更快的启动。然而,目前还没有现成的解决方案可以与Java一起部署。

对于Amazon Lambdas,您应该考虑该产品的成本和效果,因为它最终可能会带来额外的财务负担。它的主要优势在于便利性。

总结这篇观点文章,我想强调当今Java生态系统的广阔性,以及Java社区提供的处理复杂工作负载中Java启动的各种方式。现成工具的选择取决于您的应用需求,但毫无疑问,存在着不止一种方法可以使您的Java具备云原生和可持续性。拥有能够为您的开发日常提供所有这些功能深度的正确供应商,才能让您的Java之旅完美无瑕。

推荐阅读: 17.HTTP 与 HTTPS 的区别 

本文链接: 使用快速预热实现可持续的Java应用