云计算、AI、云原生、大数据等一站式技术学习平台

网站首页 > 教程文章 正文

应用无损上下线

jxf315 2025-02-10 12:51:27 教程文章 32 ℃

很多应用系统为了避免发布过程中的流量有损,一般选择在流量较小的时间段发布,虽然这样做有效果,但运维成本高,而且也不能做到应用完全无损上下线。对一些比较重要的业务系统或者并发高的系统来说,应用发布期间会有短时间服务不可用,对用户体验或业务造成影响。基于这个背景,在应用发布过程中通用解决方案是:应用下线时进行自适应等待+主动通知,应用上线时就绪检查与微服务生命周期对齐+服务预热等技术手段所提供的微服务应用无损上下线功能,能有效规避线上发布所出现的流量资损。

应用发布流量有损场景分析

应用发布常见的流量有损情况:

1.服务无法感知其他服务下线: 服务消费者感知注册中心服务列表更新存在延时(zookeeper watch 机制 client端秒级刷新本地服务缓存,nacos client 端默认30秒刷新一次本地服务缓存,eureka client 端也是默认30秒刷新一次本地服务缓存),因此服务节点下线期间,其他服务消费者没有刷新本地服务列表前还是会有流量请求到发布的服务节点上造成请求异常。

2.服务初始化数据慢:服务节点刚启动接收线上流量进行资源初始化加载,由于流量突增,会导致大量请求响应超时、阻塞、资源消耗过大导致服务节点刚启动就不能正常提供服务

3.注册太早:服务启动存在异步加载资源处理,当服务还没有真正初始化完配置,服务节点就注册到注册中心,其他服务消费者感知到服务节点上线,流量请求过来时导致请求响应慢、超时、业务异常等报错情况。

4.服务发布状态与服务运行状态不一致使用 Kubernetes 的滚动发布功能进行应用发布,由于Kubernetes 的滚动发布一般关联的就绪检查机制,是通过检查应用特定端口是否启动作为应用就绪的标志来触发下一批次的实例发布,但在微服务应用中只有当应用完成了服务注册才可对外提供服务调用。因此某些情况下会出现新应用还未注册到注册中心,老应用实例就被下线,导致无服务可用。


应用发布无损下线(优雅停机)方案

问题1:Spring Cloud 应用消费者无法及时感知提供者服务下线

方案1:阿里云微服务引擎 MSE 基于 Java Agent 字节码技术设计实现的无损下线功能如下图 2 所示:

在该套无损下线方案中,服务提供者应用仅需接入 MSE,相比一般的有损下线。应用在下线前会有一段自适应等待时期,该时期待下线应用会通过主动通知的方式,向其在自适应等待阶段发送了请求的服务消费者发送下线事件,消费者接收到下线事件后会主动拉取注册中心服务实例列表以便实时感知应用下线事件避免调用已下线实例造成应用下线流量有损。

方案2:持续交互平台流水线处理(无依赖 应用无感知)

1.发布服务节点前,先通过持续交互平台执行服务节点从注册中心下线(对接nacos、eureka 服务下线接口;zookeeper 执行shell命令删除znode 服务注册信息) ,让其他节点提前感知该服务节点下线状态,不提供服务

2.服务节点下线后 持续交互平台sleep 5秒,等待要发布的服务节点正在处理的请求尽可能处理完

3.执行stop 服务环节

4.检查服务端口与进程是否存在 ,再执行发布服务节点环节


应用无损上线方案(服务预热)

延迟加载是软件框架设计中最常见的一种策略,例如在 Spring Cloud 框架中 Ribbon 组件的拉取服务列表初始化时机默认是要等到服务的第 1 次调用时刻。通常来说第一次调用由于进行了一些资源初始化,耗时是正常情况的数倍之多。因此把新应用发布到线上直接处理大流量极易出现大量请求响应慢,资源阻塞,应用实例宕机的现象。

方案1:阿里MSE服务治理

MSE 提供的小流量预热功能通过调节刚上线应用所分配的流量帮助其在进行充分预热后再处理正常流量从而对新实例进行保护。MSE 还提供了资源预建连接、延迟注册、确保 Kubernetes 就绪检查通过前完成服务注册和确保 Kubernetes 就绪检查通过前完成服务预热等一整套无损上线手段来满足各类不同应用的无损上线需求。


方案2:通过持续发布平台延迟服务节点注册

1.延迟发布为了一些需要异步加载的前置资源如提前准备缓存资源,异步下载资源等,需要控制服务注册时机,即控制流量进入的时机保证服务所需的前置资源准备完成该服务才可以进行发布,通过延迟时间再执行服务注册逻辑

2.服务小流量预热: 通过持续交互平台调用nacos 调整服务节点权重 依次递增放大流量

3.打通k8s与微服务生命周期

K8s 提供两种健康检查机制:

  • livenessProbe,用于探测不健康的 Pod,探测失败将会重启 Pod。
  • readinessProbe,用于探测一个 Pod 是否就绪接受流量,探测失败将会在 Service 路由上摘取该节点。

如果不配置 readinessProbe ,默认只检查容器内进程是否启动运行,而对于进程的运行情况很难考量。可以通过对外提供 readiness 接口,只有 Spring Bean 初始化完成以及异步资源准备就绪并且开始服务注册时, readiness 才返回 200。将微服务侧的服务暴露与 K8s Service 体系打通,使 K8s 管控能感知到进程内部的服务就绪时机,从而进行正确地服务上线。


如何判断我们每次发布应用的无损下线是否生效?最直观的方式那就是看业务的流量,我们需要一种完善的可观测能力,帮助我们观测下线的流程有无任何问题。当出现问题的时候,需要可观测能力帮助我们快速定位问题以及根因。

最近发表
标签列表