【阅读原文】戳:CRaC技术助力ACS上的Java应用启动加速
SpringBoot等Java类应用成功运行后,真正能承载流量并顺利提供服务往往需要再做一定的数据预热过程(类加载以及JIT编译)。若预热不充分,在承载大流量条件下会引发业务进程周而复始的陷入CrashBackOff状态。基于此问题,容器计算服务借助ACS的柔性算力特性并搭配CRaC技术极致地提升Java类应用的启动速度。
什么是柔性算力?
阿里云容器计算服务ACS通过计算实例的原地资源变配能力等技术, 支持算力自适应地贴近用户实际的算力需求。柔性算力的一个典型应用场景就是应用启动加速[1]。该功能通过”灵活配置“加速系数的方式帮助Java类应用启动的时候,获得更多的算力资源并在应用启动完成后,重新降配至基准资源进而节省资源成本。配合这个功能,ACS也推荐了针对Java类应用的最佳JVM参数配置[2],推荐值有助于对于Java类应用充分利用启动加速过程中的额外算力。
什么是CRaC技术?
通过资源热变配的方式提高启动或者Crash重启时的计算资源,可以对应用启动速度进行一定程度的加速,然而应用Crash重启的场景应用仍然存在一段时间的不可服务时间,能否极大地降低启动延时甚至基本消灭重启的过程呢。
为此,研发同学瞄准了Java社区推出的CRaC机制(Coordinated Restore At Checkpoint机制)[3],即从检查点原样恢复重启)。应用可以持久化存储JVM的当前进程快照(Checkpoint点), 也就进程上下文内存状态等运行状态数据。当业务进程异常退出后,再次启动服务时可以直接通过该快照文件恢复至运行状态。基于检查点恢复应用启动速度将比较原始应用冷启动方式减少更多的启动时间,继而加快应用启动速度。CRaC基于CRIU(Checkpoint and Restore in Userspace)实现检查点和恢复功能。CRIU是一个在用户空间中实现检查点和恢复功能的项目,适用于Linux操作系统。CRaC在此基础上进行了增强和调整,使其适用于Java应用程序。
Alibaba Dragonwell是阿里巴巴内部OpenJDK定制版AJDK的开源版本,AJDK为在线电商,金融,物流做了结合业务场景的优化,运行在超大规模100,000+ 服务器的阿里巴巴数据中心。最近release 的Dragonwell版本,已经引入了增强版本的CRaC技术能力,详细参考如[4][5][6]。
如何将CRaC和柔性算力结合?
为什么不直接使用CRaC?而是选择和应用启动加速等柔性算力技术结合?这是2个维度的事情,其实从原理上分析完全可以分开使用。本文建议与“应用启动加速[7]”配合使用的目的在于缓解首次应用启动所带来的耗时问题。具体的,在应用首次启动之后,可以完成快照的创建,后续应用进程如果异常退出,可以利用已经存在的快照,近乎即时地完成应用重启。
综上所述,整体架构图如图1所示。
图 1丨 ACS容器算力中应用启动加速结合CRaC技术架构图
如何在Java类应用中集成CRaC技术?
用户在接入CRac技术时需要修改JDK的版本(替换为Dragonwell),同时在代码或脚本里面设置检查点,这部分是侵入式修改步骤,需要研发同学了解一定的CRaC技术细节。特别的,要保证:
• 所设置的检查点之前程序状态可重用。• 所设置的检查点之前程序状态不可重用,在进程被恢复的时候,额外需要将这些状态数据或业务代码逻辑通过回调(Callback)的方式进行状态恢复。
为了更直观地展示上述技术在容器计算服务ACS产品上的效果,本文通过两个对比实验来验证上述观点。
对比实验一:不使用应用启动加速能力,对比使用/不使用CRaC技术的Java类Spring-Petclinic的启动耗时。标准资源规格应用启动时间 vs 运行态过程中程序Crash之后重新拉起程序启动时间。实验统计数据如表1所示,并且实验截图如图2和图3所示。
表1:使用CRaC技术统计运行态程序Crash之后恢复进程耗时
首次启动应用 (耗时) |
运行态Crash后重启 (平均耗时) |
平均总耗时 (多次均值) |
|
使用CRaC技术 |
29.185s |
0.176s |
0.176s |
不使用CRaC技术 |
29.185s |
29.185s |
29.185s |
图2丨Spring-Petclinic程序首次启动耗时日志图
图3丨Spring-Petclinic程序运行态Crash之后利用CRaC技术将程序重新拉起耗时
对比实验二:对比实验一解决运行态过程中,遇到程序异常Crash之后能快速拉起。首次拉起应用依然会耗费较多时间,因此使用应用启动加速能力,解决首次Java类应用耗时问题。使用应用加速 + Crash后重启的整体耗时 vs 不使用应用加速 + Crash后重启的整体耗时。实验统计数据如表2和表3所示。
表2:应用启动加速结合CRaC技术的应用启动耗时
首次启动应用 (耗时) |
运行态Crach后重启 (平均耗时) |
平均总耗时 (多次均值) |
|
使用应用启动加速 (倍数=4) |
7.33s |
0.136s |
0.136s |
不使用应用启动加速 |
29.185s |
0.176s |
0.176s |
表3:应用启动加速不同CPU倍数对于Spring-Petclinic程序启动耗时
资源倍数Factor |
首次启动应用 (耗时) |
运行态Crach后重启 (平均耗时) |
平均总耗时 (多次均值) |
250m(1/2倍) |
58.597s |
0.420s |
0.420s |
500m(1倍) |
29.185s |
0.176s |
0.176s |
1(2倍) |
17.092s |
0.128s |
0.128s |
2(4倍) |
11.293s |
0.136s |
0.136s |
4(8倍) |
7.33s |
0.136s |
0.136s |
展望
CRaC技术作为一种缓存技术,适用前景广泛,尤其在Serverless、分布式和云原生系统中。特别地结合一些场景适配,能够显著提升应用服务的整体可用性和更好的用户体验。(1)在容器能力方面,如微服务或函数计算等轻量级应用,当某个服务实例发生故障时,快速从最近的保存检查点恢复,减少服务启动时间和恢复流程。(2)增强用户体验,对于服务提供方当发生故障的情况下,用户不会感觉到明显的服务中断,应用程序可以在短时间内恢复正常运行。(3)在支持新兴应用场景上,随着边缘计算、物联网IoT等新兴技术的发展,CRaC技术将在这些领域发挥重要作用。如在边缘设备上部署的应用程序可以通过CRaC实现快速恢复,确保数据和服务的连续性。
特别地,在提升资源利用率方面,更多的用户选择通过技术手段实施降本增效。通常对于Java类应用启动需消耗更多的资源,用户权衡下通常会选择使用高规格实例支持。这样的资源配比其实并不适用于日常态。为了更高效地利用计算资源,用户希望在负载较低时降低资源占用情况, 这样往往面对突发型流量时将导致算力热点产生。相关的这些探讨,后继作者团队也会结合“应用进程异常导致容器Crash发生时,动态分配更多算力,主动实施Cpu boost等相关特性分享”,着重分析“应用启动加速和CRaC缓存技术在不同场景下适用性”等问题。
附录:
为上述实验中所使用的镜像提供一个Dockerfile文件,使用者基于此构建个性化应用并体验整体过程。
1. 提供的测试代码包:
其中Alibaba_Dragonwell_Extended_11.0.25.22.9_x64_linux.tar.gz和 spring-petclinic-2.4.0.BUILD-SNAPSHOT.jar 已经编译完成,在所提供的测试镜像。
2. 自行构建请参考:
Dragonwell 11:
和spring-petclinic包:
https://github.com/dragonwell-project/dragonwell11/wiki/CRaC#%E5%87%86%E5%A4%87spring-petclinc
实验使用的镜像Dockerfile:
FROM alibaba-cloud-linux-3-registry.cn-hangzhou.cr.aliyuncs.com/alinux3/alinux3:latest # 更新系统软件 RUN dnf install -y glibc && dnf update --security -y && dnf upgrade --security -y && dnf clean all && rm -rf /var/cache/dnf/ && rm -rf /core.* # 安装基本的软件包 RUN yum install glibc net-tools tar iputils tcpdump wget iproute bind-utils openssh-clients xz procps-ng util-linux -y && yum update -y ADD app/Alibaba_Dragonwell_Extended_11.0.25.22.9_x64_linux.tar.gz /home/app ADD app/spring-petclinic-2.4.0.BUILD-SNAPSHOT.jar /home/app ADD app/run.sh /home/app ADD app/takepid.sh /home/app ENV JAVA_HOME=/home/app/jdk RUN setcap cap_checkpoint_restore+eip /home/app/dragonwell-11.0.25.22+9-GA/lib/criu RUN chmod +x /home/app/run.sh && chmod +x /home/app/takepid.sh # 设置工作目录 WORKDIR /home/app # 确保以 root 用户运行 USER root # 为了实验演示,阻塞1号进程 # ENTRYPOINT ["tail", "-f", "/dev/null"] ENTRYPOINT ["/home/app/run.sh"]
相关链接:
[1] ACS柔性算力:
[2] JVM优化调参:
[5] https://github.com/dragonwell-project/dragonwell11/wiki/CRaC
[6] 下载镜像dragonwell11:
[7] 结合CRaC技术实现JAVA类应用启动加速:
https://help.aliyun.com/document_detail/2854327.html?spm=a2c4g.11186623.help-menu-search-2584271.d_0
我们是阿里巴巴云计算和大数据技术幕后的核心技术输出者。
获取关于我们的更多信息~