【AICon】AI 基础设施、LLM运维、大模型训练与推理,一场会议,全方位涵盖! >>> 了解详情
写点什么

快速实现不打折扣的云原生 Java 应用

作者:Tobi Ajila, Thomas Watson

  • 2023-06-02
    北京
  • 本文字数:4694 字

    阅读完需:约 15 分钟

快速实现不打折扣的云原生Java应用

近年来,向云原生计算迁移一直是开发人员比较关注的事情,按照云原生方式他们的业务应用能够从减少 IT 基础设施,提高可扩展性等方面受益。当涉及到云端部署应用程序时,“伸缩至零(scale-to-zero)”是标准的供应(provisioning)策略,以便于在业务需求较低的时候降低成本。随着需求的增加,会供应更多的应用程序实例和运行时,这种扩展必须非常迅速,这样终端用户才不会遇到响应滞后的问题。运行时的启动时间会对扩展性能产生很大的影响。

 

Open Liberty是一个云原生 Java 运行时,与其他 Java 运行时类似,它是建立在 JVM 技术之上的。JVM(更广泛地说,整个 JDK)所提供的性能、调试能力和类库使其成为支撑应用程序的重要技术。尽管 JVM 以出色的吞吐能力而闻名,但是其启动时间却落后于 Go 和 C++等静态编译语言。考虑到伸缩至零的需求,所以多年以来,显著改善启动时间一直是所有 JVM 实现的关键创新领域。AppCDS(HotSpot)Shared Classes Cache(Eclipse OpenJ9)这样的元数据缓存技术在启动时间方面做出了令人瞩目的改进,但并没有在启动时间方面实现数量级级别的减少,而这恰好是 serverless 计算的扩展场景所需要的。

 

编译为原生镜像以减少启动时间

 

Graal Native Image曾经宣布,借助编译为原生的方式,它能够实现低于 100 毫秒的启动时间,因此得到很多的关注。这是 JVM 领域的一个重大转变,因为这是 Java 第一次在启动时间方面能够与 C++相抗衡。虽然 Graal Native Image 显著降低了启动时间,但这也是有一定代价的。

 

首先,静态编译要求在构建时对应用有一个全局的了解。对于开发人员来说,他们在构建应用时一直依赖的动态能力将会受到限制。比如,像反射、动态类加载和 invokedynamic 等操作均需要特殊处理,因为它们会干扰生成原生镜像时的静态分析。这意味着,我们可能需要对应用程序进行大量的修改,这样原生镜像才能够正常运行,更糟糕的是,应用程序的依赖可能也需要更新。

其次,调试会变得更具挑战性,因为我们此时调试的已经不是一个 JVM 应用,而是一个原生可执行文件。我们需要将熟悉的 Java 调试器替换为原生调试器(如gdb)来调查问题。有种解决方式是在开发环境中使用 JVM,在生产环境中使用原生镜像。但是,这意味着生产环境与开发环境是不一致的,最终我们可能必须要在两个不同的运行时中修复缺陷!

 

最后,JVM 提供的优秀的特性之一就是出色的吞吐量,即时(just-in-time)编译器能够在运行时根据实时数据优化应用程序以达到最佳性能。这一点也必须在原生镜像中牺牲掉,因为开发人员只有一次编译的机会,那就是在构建时。有些框架,比如Spring Native,已经建立了帮助 Java 开发人员在原生镜像约束下运行应用程序的能力,但不得不承认的是,开发人员必须放弃一些东西以获取原生镜像在启动时间方面的收益。

 

使用检查点/恢复功能跳过启动时间

 

Liberty 运行时采用了一种不同的方式来改善启动时间。Liberty 的目标是提供快速启动,而不必进行取舍,这是通过一项名为Liberty InstantOn的特性实现的。该特性提供了 Java 开发人员熟悉的所有功能,相对于没有使用 InstantOn 的 JVM 运行环境,它的运行时启动时间最多能够优化 10 倍。

 

从基础上来讲,Liberty InstantOn 是基于检查点/恢复(checkpoint/restore)技术的。我们启动一个应用程序,然后暂停它,并在某些明确定义的点上持久化应用程序的状态,这就是检查点。这个检查点就会成为应用镜像,当部署应用的时候,我们只需要从已保存的状态恢复镜像即可,这就是恢复,通过这种方式,应用程序就跳过了它通常要经历的启动和初始化过程(因为这些步骤已经运行过了)。

 

Liberty 使用了OpenJ9 CRIU提供的支撑功能,这是一项基于Linux CRIU的技术,它能够让任意应用均支持检查点和恢复。在 Liberty InstantOn 方式中,因为我们依然在 JVM 上运行,所以在吞吐量性能方面没有任何损失。Java 调试也能按照预期方式运行,所有依赖动态 JVM 能力的库也能正常运行。

 

解决检查点/恢复机制的局限性

 

尽管检查点/恢复的概念听起来很简单,但在现实中,会有一些限制(这是CRIU的运行方式所导致的)需要由运行时和 JVM 共同来解决,以便于让应用程序体验到这些收益。当执行检查点时(此时会构建镜像),CRIU 会将环境“冻结”在检查点状态中,包括环境变量、计算资源的信息(CPU、内存)以及时间本身的信息都会打包到镜像中。这些东西中的任何一项在恢复环境中都可能是不同的,从而导致应用程序的不一致,这是很难追踪的。此外,检查点可能会捕获一些数据,如果镜像要通过容器注册中心跨公共网络传输到部署环境中,这就不是很理想了。这些数据可能包含对端点的外部连接,而这些连接在恢复环境中可能并不存在,另外数据中还可能包含我们不想在检查点镜像中嵌入的安全令牌。

 

基于这些原因,OpenJ9 CRIU 支持内置的补偿机制,以确保在检查点保存的应用在恢复时的行为是正确和安全的。对时间敏感的 API 进行了修改以补偿检查点和恢复时的停机时间。对于像SecureRandom这样的随机 API 在恢复的时候对种子进行了重置(re-seed),以确保每次检查点恢复时,它都会被恢复为唯一的实例。

 

JVM 可以解决它所知道的所有事情,但是应用程序代码可能也需要类似的处理。Liberty 运行时通过与 JVM 合作来解决 JVM 无法自行处理的剩余问题,从而帮助开发人员摆脱检查点/恢复的复杂性。为了实现这一点,OpenJ9提供了一个钩子机制,开发人员可以利用它来注册在检查点之前和之后要执行的方法。这种机制被 Liberty 广泛采用,比如,在部署时重新解析配置,以确保为环境使用正确的配置。

 

所以,尽管 OpenJ9 提供了高效利用检查点/恢复技术的工具,但是增强现有应用程序启动时间的最简单的方式是在 Liberty 上使用 Liberty InstantOn 来运行它。Liberty InstantOn 对检查点/恢复过程进行了抽象,将开发人员的选择简化为只有几项,比如确定检查点用于应用程序启动之前还是之后。

 

总而言之,我们的终极目标是改善 Java 应用程序的云原生体验,这意味着无论采用什么样的技术,都必须要在云环境中高效运行。Liberty InstantOn 与容器技术(如 Docker 和Podman)实现了无缝集成。Liberty InstantOn 还能与KnativeOpenShift等容器引擎协作。我们完成了相关的工作以确保 Liberty InstantOn 能够在非特权模式下运行,因为这对生产环境的安全性是非常重要的。这项工作的成果正在回馈给 CRIU 项目。

 

使用自己的项目尝试一下 Liberty InstantOn

 

Liberty InstantOn 的 beta 版本已经公开可用,开发人员可以使用现有的应用程序进行尝试,以观察启动时间的改进(最多能够快 10 倍)。你只需要使用 Liberty InstantOn 工具为你的应用程序创建一个应用容器镜像即可。Open Liberty 发布了生产就绪的容器镜像,使你的应用程序可以很容易地进行容器化,以便于在容器引擎中运行,比如 Docker、Podman 或 Red Hat OpenShift 这样的 Kubernetes 环境。

 

Open Liberty 容器镜像包含了所有必要的依赖,以便于在 Open Liberty 运行时中运行应用程序。如下针对开发人员的指南描述了如何基于 Open Liberty beta-instanton 镜像(icr.io/appcafe/open-liberty:beta-instanton)创建一个带有应用程序的基础应用容器镜像,然后如何在此基础之上创建并添加一个包含检查点进程状态的层。beta-instanton 镜像包含了对 Open Liberty 创建检查点并将检查点进程存储到容器镜像层中所需的所有先决条件。这包括对 OpenJ9 CRIU 和 Linux CRIU 支持的早期访问构建。

 

如何使用 Liberty InstantOn 容器化应用程序,使其能够更快启动

如下的指南使用 Podman 来构建和运行容器,并且使用了Open Liberty入门指南中的应用程序。如果你手头有自己的应用程序,可以将其替换掉。

 

入门应用程序包含了一个Dockerfile,如下所示:

 

FROM icr.io/appcafe/open-liberty:full-java11-openj9-ubi

ARG VERSION=1.0ARG REVISION=SNAPSHOT

COPY --chown=1001:0 src/main/liberty/config/ /config/COPY --chown=1001:0 target/*.war /config/apps/

RUN configure.sh
复制代码

 

首先,开发人员需要更新 FROM 指令以使用 beta-instanton 镜像:

 

FROM icr.io/appcafe/open-liberty:beta-instanton
复制代码

 

然后,借助更新后的 Dockerfile,可以使用如下的命令构建应用容器镜像:

 

podman build –t getting-started .
复制代码

 

该命令会创建应用容器镜像,但是还没有创建检查点进程。应用程序的检查点进程是通过如下命令运行应用容器镜像来创建的,这里添加了一些额外的选项:

 

podman run \--name getting-started-checkpoint-container \--privileged \--env WLP_CHECKPOINT=applications \getting-started
复制代码

 

通过 WLP_CHECKPOINT 变量,Open Liberty 运行时声明在被配置的应用启动后但在打开端口以接受传入的请求之前对应用进程生成检查点。当应用程序进程完成检查点生成后,运行中的容器将会停止。这将会形成一个包含检查点进程状态的已停止的容器。

 

最后一步是将这个检查点进程状态以层的形式添加到原始应用程序的进程镜像中。这可以通过如下的命令将名为 getting-started-checkpoint-container 的已停止应用容器提交给一个新的容器镜像:

 

podman commit \getting-started-checkpoint-container \getting-started-instanton
复制代码

 

最终的结果是可运行的 getting-started-instanton 容器镜像。

 

运行具有 Linux 特权能力的容器

当运行 getting-started-instanton 容器时,开发人员必须授予其一组Linux能力,以便容器镜像中的 CRIU 二进制文件执行恢复过程:

 

  • cap_checkpoint_restore

  • cap_net_admin

  • cap_sys_ptrace

 

在创建检查点进程时,使用了一个具有特权的容器,它授予了容器镜像中的 CRIU 二进制文件所需的Linux能力

 

请通过如下的 Podman 命令以运行具有三种所需能力的容器:

podman run \--rm \--cap-add=CHECKPOINT_RESTORE \--cap-add=NET_ADMIN \--cap-add=SYS_PTRACE \-p 9080:9080 \getting-started-instanton
复制代码

 

getting-started-instanton 容器会以必要的权限来运行,以执行恢复过程,应用程序的运行速度要比原始的 getting-started 应用程序快 10 倍。

 

未来的改进

 

Open Liberty的beta版本发布了对 Liberty InstantOn 的定期更新。未来的版本已经规划了一些改进,它们将会让 Liberty InstantOn 构建和运行应用镜像变得更加容易。例如,为了消除对 NET_ADMIN Linux能力的要求,一些额外的相关工作已经完成。还有一项计划是在恢复应用的过程中移除对 SYS_PTRACE 能力的要求。这将减少运行应用所需的能力清单,在运行应用程序的时候,仅需 CHECKPOINT_RESTORE 能力即可。

 

其他规划包括在应用容器的构建步骤中执行应用进程检查点,这样不需要容器运行和容器提交命令就能将应用进程状态存储到应用容器镜像层中了。

 

请反馈你们的想法

 

虽然云原生需要对组织的业务方式做出许多变化,但是有了 Liberty InstantOn,开发人员就不用担心改变他们的应用开发方式了。

 

我们鼓励开发人员使用 Open Liberty 22.0.0.11-beta 或后续版本来尝试Liberty InstantOn的beta功能。欢迎通过项目的邮件列表进行反馈。如果遇到问题,开发人员可以在StackOverflow上发布问题。如果发现缺陷的话,欢迎提交issue

 

背景说明

 

Open LibertyEclipse OpenJ9均是开源项目。IBM 基于这些项目构建了其商业的WebSphere Liberty Java 运行时和IBM Semeru Runtimes Java 发行版。Liberty InstantOn 使用了 Linux Checkpoint/Restore In Userspace(CRIU)项目提供的检查点/恢复技术,并与 CRIU 合作,将代码反馈给该项目。

 

原文链接:


https://www.infoq.com/articles/rapid-startup-of-your-cloud-native-java/

 

相关阅读:


Java 是如何毁掉你的编程思维的?

系统学 Java,看这篇 Java 综合笔记万字总结就够了!..

Java 8 之后的新特性都是鸡肋吗?

扫盲篇:Java 中为啥一个 main 方法就能启动项目?

2023-06-02 11:009976

评论 1 条评论

发布
用户头像
这种native程序应该是像Rust那样内存安全的吧?
2023-06-03 23:35 · 湖南
回复
没有更多了
发现更多内容

图文DEMO并茂讲解RecyclerView滑动时回收和复用触发的时机

android 程序员 移动开发

Android线程思考

轻口味

android 多线程 11月日更

在线等!阿里、百度一面就惨遭吊打,kotlin语言书籍

android 程序员 移动开发

坊间传言:程序员可以先在大厂镀金,以后去中小厂毫无压力

android 程序员 移动开发

基本功---Litho的使用及原理剖析,10年阿里开发架构师经验分享

android 程序员 移动开发

大厂一步到位:Android-基础+Android高级,android物联网开发从入门到实战

android 程序员 移动开发

天高任鸟飞,在你还苦闷Android出路时,总有人在系统钻研为高级开发做准备

android 程序员 移动开发

国庆节不知道学什么?这份 Android 优秀技术文章清单请收下

android 程序员 移动开发

太强了吧,这居然是19年双非本科开发一年的Android面经总结!开发几年的老程序员自叹不如

android 程序员 移动开发

大牛耗时一年:深入探索-Android-包体积优化,共三万字建议收藏上

android 程序员 移动开发

[ CloudWeGo 微服务实践 - 番外 ] Go 代码静态检查

baiyutang

golang 11月日更

在-View-上使用挂起函数,app开发面试题及答案

android 程序员 移动开发

大众点评App的短视频耗电量优化实战,通宵都要看完这个Android关键技术点

android 程序员 移动开发

太卷了!程序员面试前刷面经“神似,2021最新Android大厂面试真题大全

android 程序员 移动开发

事务是如何影响你的系统(二)

卢卡多多

11月日更

在Android项目中接入Flutter,在Flutter使用安卓布局---草稿

android 程序员 移动开发

头条Android 岗年薪45W+面经分享(技术 6面,Android开发者值得深入思考的几个问题

android 程序员 移动开发

“神算子”上线!EasyDL时序预测模型零门槛轻松上手

百度大脑

人工智能 百度

在中国程序员是青春饭吗?,android开发基础入门教程

android 程序员 移动开发

基于Android的特征X射线谱识别系统的开发,android指纹识别

android 程序员 移动开发

备战秋招-阿里巴巴面试真题:-给你一个Demo-你如何快速定位ANR?

android 程序员 移动开发

大学毕业做音视频开发,月入20K,你呢,kotlin协程面试

android 程序员 移动开发

大牛耗时一年:深入探索-Android-包体积优化,共三万字建议收藏上(1)

android 程序员 移动开发

图解:HTTP 范围请求,助力断点续传,android游戏开发入门

android 程序员 移动开发

备战金九银十:Android面试10+个知识点总结宝典助你通关

android 程序员 移动开发

备战阿里面试一年半顺利通过二面,面对突如其来的疫情,让我的阿里三面搁浅ing

android 程序员 移动开发

大神一招搞定:ReentrantReadWriteLock-几道小小数学题就够了。

android 程序员 移动开发

图解:HTTP 范围请求,助力断点续传(1),成功入职腾讯月薪45K

android 程序员 移动开发

大学计算机专业,什么水平可以进大厂?,解密Android开发常见误区

android 程序员 移动开发

太难为我这个应届生了,腾讯面试了8轮,终拿下腾讯Android测发岗offer

android 程序员 移动开发

大型Bat面试知识总结分享—AMS在Android起到什么作用?简单的分析下Android的源码

android 程序员 移动开发

快速实现不打折扣的云原生Java应用_服务革新_InfoQ精选文章