当前位置:Java -> 超快速启动解决方案的五个Java开发者必备条件
许多承诺为无服务器Java应用程序提供超快启动时间的解决方案,要么会牺牲开发者体验、吞吐性能或安全性。我们将向您展示如何在无需做出这些妥协的情况下实现Java应用程序的超快启动。
比如,您正在编写一个Java网络服务,提供您的企业销售的商品目录。在低峰时段,您的应用程序需要停止所有不需要的目录服务实例,以便您的企业不必支付不必要的云费用;在高峰时段,您的应用程序需要快速启动更多实例,以便您的客户在您的网站上获得即时的响应时间。这就是“零扩展”,您的应用程序需要快速执行。
最近出现了多种加快Java启动速度的解决方案,从编译原生镜像(从编译应用程序中删除JVM,这是Java应用程序的启动速度瓶颈)到在启动后对应用程序进行快照,从而在恢复时不需要完成启动任务。但大多数这些解决方案都会影响开发者体验、吞吐性能或安全性。
极大地改善Java应用程序启动时间的解决方案应该具备以下特点:
我们将简要介绍这些要点,并描述我们如何通过Liberty InstantOn实现了它们。
Liberty InstantOn是面向无服务器环境中Java应用程序快速启动的检查点/还原解决方案。与其他解决方案不同,Liberty InstantOn是由JDK(IBM Semeru Runtimes,OpenJDK的免费版本和Eclipse OpenJ9)的开发团队和应用程序运行时(Open Liberty,一个开源的Java应用程序运行时)的开发团队从一开始共同设计的。这种合作反映了必须在应用程序运行时和JDK之间协作完成的许多检查点和还原任务:对Liberty进行了多项更改,延迟任务直到检查点之后(例如,延迟Liberty安全功能的初始化)或在检查点之前完成任务(例如,等待后台任务完成,如正在进行的JIT编译和Liberty特定的初始化程序)。
我们测试了三种不同的应用程序的性能,分别为不使用(基准线)和使用 Liberty InstantOn,测量了应用程序的启动时间以及处理第一个请求所需的时间。请查看以下两个图表以获取结果,还可以参考我们的博客了解 方法细节。这三个应用程序分别是一个非常简单的应用,只有一个 REST 端点 (pingperf),通过使用 JPA 和远程数据库的更复杂的应用(Rest Crud),以及使用 MicroProfile 特性的完整应用(AcmeAir 微服务主服务)。
除了提供非常快的启动和首次响应时间外,协作式的 Liberty InstantOn 检查点/恢复方法还比完全删除 JVM 或仅在 JDK 层面实现检查点/恢复解决方案并且仅在表示许多种类任务不应在检查点之前完成的情况下提供更好的开发人员体验。
仅在 JDK 层面设计的检查点/恢复解决方案会迫使您作为应用程序开发人员思考低级别 OS 工具 CRIU 的工作原理以及如何设置它。此外,还需要弄清楚何时对应用程序进行检查点操作,如何确保在检查点时应用程序处于安全状态,如何确保应用程序运行时和 JVM 也处于安全状态(而又无法对其进行控制),以及如何确保这三者(应用程序、应用程序运行时和 JVM)在稍后能够正常恢复。虽然必须在 JDK 层面提供检查点/恢复支持(以便 Java 应用程序无需直接与 CRIU 接口),但与更高层次的应用程序运行时(如 Liberty)良好集成可以减轻您的负担,使您能够专注于应用程序的业务逻辑。
使用 Liberty InstantOn,只需将您的 Java 应用程序容器化,即可使其启动更快。在构建配置中,您只需选择何时进行检查点(在两个方面中的一个,“beforeAppStart” 和 “afterAppStart”),其余操作将由 Liberty 和 Semeru 透明地处理。然后,您只需在 官方 Open Liberty 容器镜像上构建一个应用程序层,其中包括 Semeru 和其他所需的一切。
从应用程序中删除 JVM 的快速启动解决方案会改变您开发应用程序的思考方式。 此外,大多数企业软件都很复杂,具有大量的组件复用。对其他开源项目的任何依赖可能意味着无限期地等待所有这些项目都正确更新以符合可以在没有 JVM 的情况下工作的标准 Java 功能的子集。
Liberty InstantOn可以执行各种任务,使您能够坚持使用您熟悉的关于Java应用程序应该工作的心智模型。动态类加载、反射和动态JIT编译都是您习惯在您的应用程序中使用的东西,并且只是您作为Java开发人员的思考的一部分。Liberty InstantOn 与 Semeru Cloud Compiler 无缝配合,可以实现JIT编译的优势,而不会给每个已恢复的应用程序实例增加内存和CPU负载。 Liberty InstantOn 还支持通常的API规范,无论是旧的还是新的,包括Jakarta EE,MicroProfile和 Spring Boot(目前正在测试版中)。 因此,您的新应用程序以及现有应用程序都可以被容器化以实现更快的启动。
想象一下,现在是凌晨4点,您被召唤出去诊断生产应用程序中的问题。 一个快速启动的本地镜像解决方案将要求您重新编译应用程序并重建应用程序容器镜像,以便调试需要进一步诊断信息的问题,或者禁用某些配置或优化。
有了Liberty InstantOn,您的运维团队已经为您收集了跟踪信息,因为他们可以轻松地重新部署您的应用程序实例,并打开方法跟踪,而无需重新编译应用程序。Liberty 和 Semeru 让您能够在恢复时间重新配置部署,并随后进行更改。这些服务性的更改支持一些实际用例,比如在部署(恢复)时间启用方法跟踪,或者改变一些 Liberty 的行为以解决问题,重要的是,你作为一个开发人员,在构建应用程序容器镜像时,不需要考虑大多数这些服务性的问题,因为它们都由 Liberty InstantOn 处理。
在规模化到零和容器部署使得启动时间成为一个重要的性能指标的情况下,应用的吞吐量仍然是一个关键的考虑因素,因为它最终会影响长期运行服务的成本。 如果您通过从您的应用程序删除JVM以提高启动速度,您将失去动态JIT编译和Java的垃圾收集(GC)技术的优势。使用猜测优化的动态JIT编译是Java平台的一个重要的价值主张。
保留JVM与 Liberty InstantOn 意味着您的应用程序将获得Java的动态JIT编译和GC技术的所有优点,这些优势已经经过几十年在 Semeru JDK 中的完善。被恢复的容器只需从之前的检查点继续执行,因此通常达到与传统的不使用 InstantOn 的 Liberty 容器相同或非常接近的峰值吞吐量(正如您可以在之前描述的相同三个应用程序的测试图中看到的)。
快速启动的检查点/恢复解决方案可能会损害企业部署的最重要的考虑之一:安全性。
首先,Liberty InstantOn不要求应用程序以root身份运行,也不要求使用特权容器。Liberty 和 Semeru 开发团队与 CRIU 项目合作,减少了在恢复时所需的 Linux 能力集,使其成为一个足够小的集合,以至于在生产中没有安全顾虑(详见我们如何为快速Java启动开发Eclipse OpenJ9 CRIU支持),团队打包了 Liberty 和 Semeru 容器镜像,因此您无需自己管理 Linux 能力。
其次,如果将敏感信息(例如加密密钥)包含在容器镜像中,然后将镜像发布到容器仓库,那么敏感信息可能会受到损害;此类敏感信息必须仅保留在部署环境中。 Semeru JDK 禁止在检查点之前使用大多数加密算法。在 Liberty 上构建的应用程序只在恢复时打开网络连接,通常这是需要加密密钥和其他机密信息的地方。对于仍然允许在检查点端进行的有限加密操作,Semeru 确保清除所有敏感信息,以便检查点中没有安全风险。
虽然有一系列方法来改进用于无服务器计算的Java启动时间,关键是开发人员的体验要尽可能顺畅,以便不要给应用程序开发人员增加不必要的额外责任、学习和努力。我们再次强调,解决方案必须:
我们努力解决了我们基于检查点/还原的解决方案中的所有这些要求,不仅适用于新应用程序,还适用于现有应用程序。 Liberty InstantOn旨在在不影响生产性能的情况下提供出色的开发人员体验。 尽管在Liberty InstantOn中仍然存在一些局限性,但它们已经清楚和公开记录,同时团队仍在努力解决这些问题。 与此同时,我们继续扩展对Jakarta EE和MicroProfile功能的支持InstantOn支持。 因此,准备好你的应用程序并试一试吧。
推荐阅读: 15.如何判断对象是否可以回收
本文链接: 超快速启动解决方案的五个Java开发者必备条件