容器化Java程序秒级弹性伸缩实践

news/2024/11/16 16:01:29/

当前许多数字化转型企业都会将自己的系统微服务化、容器化,这些技术和策略可以帮助企业更有效地利用资源、提高开发运维效率,并且在处理不同流量场景下保证系统的稳定性和性能。

弹性扩缩容

在虚拟机时代,资源的占用和维护成本较高,因为承载容量是固定的,导致了大量资源的闲置。而在容器时代,借助开源的Kubernetes等方案,我们可以更灵活地利用资源,根据需要动态调整资源的分配。弹性伸缩涉及到的相关技术解决方案:HPA、无损上线、无损下线、秒级启动。

水平Pod自动伸缩(HAP Horizontal Pod Autoscaling)

apiVersion: autoscaling/v2beta2
kind: HorizontalPodAutoscaler
metadata:name: your-java-app-hpa
spec:scaleTargetRef:apiVersion: apps/v1kind: Deploymentname: your-java-appminReplicas: 1maxReplicas: 10metrics:- type: Resourceresource:name: cputargetAverageUtilization: 50

上面的例子,是将CPU利用率配置为50%,根据应用程序的负载情况,Kubernetes将自动调整Pod的副本数,最小1个,最大10个pod。除了CPU,还可以使用内存和一些结合监控扩展的自定义指标。

通过HPA技术,不需要那么谨慎的为业务系统分配固定资源。比如之前的业务系统分配的CPU有为4核,但日常使用率仅20%,那这时我们可以给他分配2核,理论上CPU使用率就提升到了40%左右,当遇到CPU升高时可以通过扩容解决,这样能有效解决资源利用率使用过低问题。

无损上线

在小流量场景下,一般不会在调⽤时出现 Connection refused 和 No instance 等现象,但在流量高峰需要扩容时类似问题会比较明显。一般的解决方式是小流量预热。⼩流量预热⽅法主要是通过在服务消费端根据各个服务提供者实例的启动时间计算权重,结合负载均衡算法控制刚启动应⽤流量,随启动时间逐渐递增到正常⽔平,如下图所示。

将⾃身的预热时⻓和服务启动时长为参数,通过⼩流量服务预热模型计算公式进行权重流量分配,感兴趣的可以参考开源Dubbo的技术实现。

无损下线

虚机场景

虚机场景下的无损下线只需要注意服务下线时新流量不在进入已进入系统流量处理完毕,就能保证服务下线流量无损,具体步骤见下图。

• 主动注销我们应用服务下线前,主动通知注册中心注销该实例;

• 通知下线信息我们会在服务端实例下线前主动通知客户端,该服务节点下线的信息

• 调用其他提供者我们在客户端增强其负载均衡能力,在服务端下线后,客户端主动调用其他服务提供者节点。

容器场景

服务的启停不只是系统进程启停,涉及到Pod的生命周期,下面是一个pod的简单生命周期。

1. 新建pod:通过Kubernetes调度器,调度到合适的服务器中,并准备所需的算力、存储和网络等基础资源;

2. 拉取业务系统镜像:拉取业务系统Docker镜像,拉取镜像的时间取决于网络、镜像大小和是否用到P2P加速镜像拉取技术;

3. 启动业务系统:启动业务服务进程,目前行内微服务采用的是基于Java语言的Spring Cloud微服务技术,为了提升开发效率,Spring Cloud集成了大量的开源组件,加之业务系统代码及其所依赖的大量第三方组件,Web容器启动时需要加载大量上述组件,并通过Spring维护其复杂的关联关系;

4. 启动健康检查:主要目的是确保pod健康,若业务应用配置为1分钟,则在容器启动1分钟后开始进行Liveness健康检查,如果探测连续超过一定的失败次数,Kubernetes会认为服务不可用,pod会被销毁并重建。在滚动发布场景下,当一个pod的Liveness探活成功后,才能开始下一个节点的发布,可以把健康检查-启动时间改为第1分钟(具体要结合各个业务系统自身的启动时间来定),增加每30秒探活一次,失败3次后重启(结合业务系统测试而定),这样可以缩短整个版本滚动发布时长。

5. 容器优雅终止:当接到删除pod命令时,Kubernetes会给pod中容器一定的时间优雅停止,并触发preStop钩子执行微服务无损下线脚本(适用于配置有无损下线脚本微服务),实现流量无损下线。目前默认是30秒,设定时间越长越能保证流量完全无损下线,但整体滚动发版时间会被拉长,具体还需要根据业务自身情况设定;

6. 销毁pod:Kubernetes对算力、存储和网络等基础资源的释放。若应用配置固定IP,销毁pod则需要约8秒。

所以在基于Kubernetes的容器场景下,关闭一个系统是关闭一个pod,并且还需要在容器中添加钩子配置,调用系统优雅下线功能,需要注意的是容器最终宽限期terminationGracePeriodPeriods的时长大于优雅下线的时长,否则会被强制销毁。

提升启动速度

对于基于Java开发的业务系统,可以尝试使用:

  • 探索高版本Spring Boot、JDK等开源技术解决方案,调研AppCDS、CRaC等启动加速技术;

  • 探索平台框架启动速度提升方案,优化核心功能代码启动速度,支持组件按需加载;

  • 制定系统级优化启动速度技术规范,建设系统启动时间分析工具,指导业务系统进行代码优化,补齐应用启动生命周期的可观测能力;

  • 也可以尝试Serverless技术,将有潮汐场景的系统,改造为函数模式,可以进一步提升启动速度和资源利用率。

总结

数字化转型已成为企业提高效率和竞争力的重要途径。我们讨论了在微服务化和容器化过程中,利用弹性扩缩容技术提高资源利用率和开发运维效率的方法。通过水平Pod自动伸缩(HPA)、无损上线、无损下线和提升启动速度等技术,企业能够更灵活地应对不同的业务场景和需求,实现资源的最大化利用和系统的稳定性提升。

参考:

  • 《微服务治理技术白皮书》

  • Spring boot 2.3优雅下线,距离生产还有多远?-阿里云开发者社区 (aliyun.com)


http://www.ppmy.cn/news/1423083.html

相关文章

Zynq学习笔记--数字视频帧以及同步信号

目录 1. 介绍 2. 重要概念 3. 仿真测试 4. 总结 1. 介绍 Zynq芯片,作为一款集成了高性能FPGA和ARM处理器的系统级芯片(SoC),为视频处理提供了强大的硬件支持。该芯片内置的丰富视频方面的IP模块,使得从事视频处理项目的开发者能够高效、…

论文阅读--Conservative Q-Learning for Offline Reinforcement Learning

摘要 在强化学习( RL )中有效地利用以前收集的大量数据集是大规模实际应用的关键挑战。离线RL算法承诺从先前收集的静态数据集中学习有效的策略,而无需进一步的交互。然而,在实际应用中,离线RL是一个主要的挑战,标准的离线RL方法…

详解番茄小说推文如何申请授权,助力你选视频副业收入更上一层楼

小说推文,就是发布小说类视频作品,引导用户到小说平台观看小说。该项目门槛较低,很适合新手,无需高超的技术水平,因此一直备受副业人群关注,尤其是番茄小说平台,因其高佣稳定的优势,…

金蝶云星空与金蝶云星空对接集成委外超耗查询连通生产订单变更(发顺丰)

金蝶云星空与金蝶云星空对接集成委外超耗查询连通生产订单变更(发顺丰) 对接系统金蝶云星空 金蝶K/3Cloud在总结百万家客户管理最佳实践的基础上,提供了标准的管理模式;通过标准的业务架构:多会计准则、多币别、多地点、多组织、多税制应用框…

Unity之OpenXR+XR Interaction Toolkit快速监听手柄任意按键事件

前言 当我们开发一个VR时,有时希望监听一个手柄按键的点击事件,或者一个按钮的Value值等。但是每次有可能监听的按钮有不一样,有可能监听的值不一样,那么每次这么折腾,有点累了,难道就没有一个万能的方法,让我可以直接监听我想要的某个按钮的事件么? 答案是肯定的,今…

Keil MDK下如何设置非零初始化变量 及变量指定位置- Arm CompilerV5 和 V6区别

目录 一、Arm CompilerV51.定义变量时,使用编译器扩展属性__attribute__((section("name"), zero_init))来将变量放入指定段中。其中section("name")选择一个指定的段,zero_init告诉编译器将变量放入ZI段。 二、Arm CompilerV61.定义…

建造者模式:构造复杂对象的艺术

在面向对象的设计中,建造者模式是一种重要的创建型设计模式,专门用来构建复杂的对象。它主要目的是将对象的构造代码与其表示代码分离,使同样的构建过程可以创建不同的表示。本文将详细介绍建造者模式的定义、实现、应用场景以及优缺点&#…

算法练习第19天|222.完全二叉树的节点个数

222.完全二叉树的节点个数 222. 完全二叉树的节点个数 - 力扣(LeetCode)https://leetcode.cn/problems/count-complete-tree-nodes/description/ 题目描述: 给你一棵 完全二叉树 的根节点 root ,求出该树的节点个数。题目数据保…