【音频】微服务线上发布稳定性解决方案|学习笔记

本文涉及的产品
云原生网关 MSE Higress,422元/月
服务治理 MSE Sentinel/OpenSergo,Agent数量 不受限
注册配置 MSE Nacos/ZooKeeper,118元/月
简介: 快速学习【音频】微服务线上发布稳定性解决方案

开发者学堂课程【微服务治理技术进阶【音频】微服务线上发布稳定性解决方案】学习笔记,与课程紧密联系,让用户快速学习知识。  

课程地址:https://developer.aliyun.com/learning/course/1033/detail/15133


【音频】微服务线上发布稳定性解决方案

内容介绍:

一、无损上下线背景

二、发布态与运行态未对齐

三、无损下线

四、主动通知

五、延迟注册

六、小流量服务预热

微服务治理技术解决方案有很多,例如无损发布、全链路灰度、限流降级等,本次播客摘自《微服务治理技术白皮书》的第三章第1节《微服务线上发布稳定性解决方案》。

绝大多数的软件应用生产安全事故发生在应用上下线发布阶段,尽管通过遵守业界约定俗成的可灰度,可观测和可滚回的安全生产三板斧,可以最大限度的规避发布过程中由于应用自身代码问题对用户造成的影响。

但对于高并发大流量情况下的短时间流量有损问题却仍然无法解决。因此,本节将围绕发布过程中如何解决流量有损问题实现应用发布过程中的无损上下线效果相关内容展开方案介绍。

一、无损上下线背景

据统计,应用的事故大多发生在应用上下线过程中,有时是应用本身代码问题导致。但有时我们也会发现尽管代码本身没有问题,但在应用上下线发布过程中仍然会出现短时间的服务调用报错,比如调用时出现 Connection refused 和 No instance 等现象。相关问题的原因有相关发布经历的同学或多或少可能有一定了解,而且大家发现该类问题一般在流量高峰时刻尤为明显,半夜流量少的时候就比较少见,于是很多人便选择半夜三更进行应用发布希望以此来规避线上发布事故。本节将就这些问题出现的背后真实原因以及业界对应的设计方案展开介绍。常见的流量有损现象出现的原因包括但不限于以下几种

1、服务无法及时下线

服务消费者感知注册中心服务列表存在延时,导致应用特定实例下线后在一段时间内服务消费者仍然调用已下线实例造成请求报错。

2、初始化慢

应用刚启动接收线上流量进行资源初始化加载,由于流量太大,初始化过程慢,出现大量请求响应超时、阻塞、资源耗尽从而造成刚启动应用宕机。

3、注册太早

服务存在异步资源加载问题,当服务还未初始化完全就被注册到注册中心导致调用时资源未加载完毕出现请求响应慢、调用超时报错等现象。

二、发布态与运行态未对齐

使用 Kubernetes 的滚动发布功能进行应用发布,由于 Kubernetes 的滚动发布一般关联的就绪检查机制,是通过检查应用特定端口是否启动作为应用就绪的标志来触发下一批次的实例发布,但在微服务应用中只有当应用完成了服务注册才可对外提供服务调用。因此某些情况下会出现新应用还未注册到注册中心老应用实例就被下线,导致无服务可用。接下来,将就具体的下线和上线过程中如何避免流量损耗问题进行分别介绍。

三、无损下线

由于微服务应用自身调用特点,在高并发下,服务提供端应用实例的直接下线,会导致服务消费端应用实例无法实时感知下游实例的实时状态因而出现继续将请求转发到已下线的实例从而出现请求报错,流量有损。例如对于 SpringCloud 应用如图1所示,当应用的两个实例 A’和 A 中的 A 下线时,由于 Spring Cloud 框架为了在可用性和性能方面做平衡,消费者默认是 30s 去注册中心拉取最新的服务列表,因此 A 实例的下线不能被实时感知,流量较大时,消费者会继续通过本地缓存调用已下线的 A 实例导致出现流量有损。基于上述背景,业界提出了相应的无损下线(也叫优雅下线)的技术方案来应对上述问题。本节将对业界主流的一些无损下线技术方案进行介绍。针对该类问题,业界一般的解决方式是通过将应用更新流程划分为手工摘流量、停应用、更新重启三个步骤。由人工操作实现客户端避免调用已下线实例,这种方式简单而有效,但是限制较多;不仅需要借助流控能力来实现实时摘流量,还需要在停应用前人工判断来保证在途请求已经处理完毕。这种需要人工介入的方式运维复杂度较高,只适用于规模较小的应用,无法解决当前云原生架构下,自动化的弹性伸缩、滚动升级等场景中的实例下线过程中的流量有损问题。本节将对业界应用于云原生场景中的一些无损下线技术方案进行介绍。

四、主动通知

一般注册中心都提供了主动注销接口供微服务应用正常关闭时调用,以便下线实例能及时更新其在注册中心上的状态。主动注销在部分基于事件感知注册中心服务列表的微服务框架,比如 Dubbo 中能及时让上游服务消费者感知到提供者下线避免后续调用已下线实例。但对于像 Spring Cloud 这类微服务框架服务消费者感知注册中心实例变化是通过定时拉取服务列表的方式实现。尽管下线实例通过注册中心主动注销接口更新了其自身在注册中心上的应用状态信息但由于上游消费者需要在下一次拉取注册中心应用列表时才能感知到,因此会出现消费者感知注册中心实例变化存在延时。在流量较大,并发较高的场景中,当实例下线后,仍无法实现流量无损。既然无法通过注册中心让存量消费者实例实时感知下游服务提供者的变化情况,业界提出了利用主动通知解决该类问题。主动通知过程如图2所示,服务提供者 B 中某个实例在下线时为避免主动在注册中心中注销的服务实例状态无法实时被上游消费者 A 感知到,从而导致调用已下线实例的问题。在接收到下线命令即将下线前,提供者 B 对于在等待下线阶段内收到的请求,在其返回值中都增加上特殊标记,让服务消费者接收到返回值,并识别到相关标志后主动拉取一次注册中心服务实例从而实时感知 B 实例最新状态,从而达到服务提供者的下线状态能够被服务消费者实时感知。

在并发度不高的场景下,主动通知方法可以解决绝大部分应用下线流量有损问题。但对于高并发大流量应用下线场景,如果主动通知完,可能仍然存在一些在途请求需要待下线应用处理完才能下线否则这些流量就无法正常被响应。为解决该类在途请求问题,可通过给待下线应用在下线前通过自适应等待机制在处理完所有在途请求后,再下线以实现流量亏损。如图3所示,自适应等待机制是通过待下线应用统计应用中是否仍然存在未处理完的在途请求,来决定应用下线的时机,从而让待下线应用在下线前处理完所有剩余请求。

延迟加载是软件框架设计过程中最常见的一种策略,例如在 Spring Cloud 框架中Ribbon 组件的拉取服务列表初始化默认都是要等到服务的第一次调用时刻,例如图4是 Spring Cloud 应用中第一次和第二次通过调用 RestTemplate 调用远程服务的耗时对比情况,由图4结果可见,第一次调用由于进行了一些资源初始化,耗时是正常情况的数倍之多。因此把新应用发布到线上直接处理大流量极易出现大量请求响应慢,资源阻塞,应用实例宕机的现象。业界针对上述应用无损上线场景提出如下包括延迟注册、小流量服务预热以及就绪检查等一系列解决方案。

五、延迟注册

对于初始化过程需要异步加载资源的复杂应用启动过程,由于注册通常与应用初始化过程同步进行,从而出现应用还未完全初始化就已经被注册到注册中心供外部消费者调用,此时直接调用由于资源未加载完成可能会导致请求报错。通过设置延迟注册,可让应用在充分初始化后再注册到注册中心对外提供服务。例如开源微服务治理框 Dubbo 原生就提供延迟注册功能。

六、小流量服务预热

在线上发布场景下,很多时候刚启动的冷系统直接处理大量请求,可能由于系统内部资源初始化不彻底从而出现大量请求超时、阻塞、报错甚至导致刚发布应用宕机等线上发布事故出现。为了避免该类问题业界针对不同框架类型以及应用自身特点设计了不同的应对举措,比如针对类加载慢问题有编写脚本促使 IVM 进行预热、阿里巴巴集团内部 HSF(High Speed Framework) 使用的对接口分批发布、延迟注册、通过 mock 脚本对应用进行模拟请求预热以及小流量预热等。本节将对其中适用范围最广的小流量预热方法进行介绍。相比于一般场景下,刚发布微服务应用实例跟其他正常实例一样一起平摊线上总 QPS。小流量预热方法通过在服务消费端根据各个服务提供者实例的启动时间计算权重,结合负载均衡算法控制刚启动应用流量随启动时间逐渐递增到正常水平的这样一个过程帮助刚启动运行进行预热,详细QPS 随时间变化曲线如图6所示。

开源 Dubbo 所实现的小流量服务预热过程原理如图7所示。服务提供端在向注册中心注册服务的过程中,将自身的预热时长 WarmupTime、服务启动时间 StartTime 通过元数据的形式注册到注册中心中,服务消费端在注册中心订阅相关服务实例列表,调用过程中根据 WarmupTime,StartTime 计算个实例所分批的调用权重,刚启动 StartTime 距离调用时刻差值较小的实例权重下,从而实现对刚启动应用分配更少流量实现对其进行小流量预热。

开源 Dubbo 所实现的小流量服务预热模型计算如下公式所示模型中应用 QPS 对应的 f(x) 随调用时刻x线性变化,x 表示调用时刻的时间,startTme 是应用开始时间,warmupTime 是用户配置的应用预热时长,k 是常数,一般表示各实例的默认权重。

相关文章
|
1月前
|
Dubbo Java 应用服务中间件
Spring Cloud Dubbo:微服务通信的高效解决方案
【10月更文挑战第15天】随着信息技术的发展,微服务架构成为企业应用开发的主流。Spring Cloud Dubbo结合了Dubbo的高性能RPC和Spring Cloud的生态系统,提供高效、稳定的微服务通信解决方案。它支持多种通信协议,具备服务注册与发现、负载均衡及容错机制,简化了服务调用的复杂性,使开发者能更专注于业务逻辑的实现。
56 2
|
1月前
|
XML JSON API
ServiceStack:不仅仅是一个高性能Web API和微服务框架,更是一站式解决方案——深入解析其多协议支持及简便开发流程,带您体验前所未有的.NET开发效率革命
【10月更文挑战第9天】ServiceStack 是一个高性能的 Web API 和微服务框架,支持 JSON、XML、CSV 等多种数据格式。它简化了 .NET 应用的开发流程,提供了直观的 RESTful 服务构建方式。ServiceStack 支持高并发请求和复杂业务逻辑,安装简单,通过 NuGet 包管理器即可快速集成。示例代码展示了如何创建一个返回当前日期的简单服务,包括定义请求和响应 DTO、实现服务逻辑、配置路由和宿主。ServiceStack 还支持 WebSocket、SignalR 等实时通信协议,具备自动验证、自动过滤器等丰富功能,适合快速搭建高性能、可扩展的服务端应用。
105 3
|
14天前
|
Java 网络安全 Nacos
Nacos作为流行的微服务注册与配置中心,其稳定性和易用性备受青睐。
Nacos作为流行的微服务注册与配置中心,其稳定性和易用性备受青睐。然而,实际使用中常遇到“客户端不发送心跳检测”的问题。本文深入探讨该问题的原因及解决方案,帮助开发者快速定位并解决问题,确保服务正常运行。通过检查客户端配置、网络连接、日志、版本兼容性、心跳策略、注册状态、重启应用和环境变量等步骤,系统地排查和解决这一问题。
34 3
|
4月前
|
数据库 开发者 微服务
微服务架构下的数据一致性挑战与解决方案
在当今的软件开发领域,微服务架构因其灵活性和可扩展性而受到广泛青睐。然而,这种架构风格也带来了数据一致性的复杂问题。本文将深入探讨微服务环境中数据一致性面临的挑战,并提出一系列解决策略。我们将以实际案例分析如何应用这些策略,并讨论它们在不同场景下的利弊。文章旨在为后端开发者提供一套实用工具和方法,帮助他们在设计和实现微服务时确保数据一致性。
146 0
|
3月前
|
API 微服务
【Azure 微服务】面对Service Fabric中节点状态不正常(Disabling/Warning/RemoveNode)的几种尝试解决方案
【Azure 微服务】面对Service Fabric中节点状态不正常(Disabling/Warning/RemoveNode)的几种尝试解决方案
|
4月前
|
关系型数据库 分布式数据库 数据库
PolarDB,阿里云的开源分布式数据库,与微服务相结合,提供灵活扩展和高效管理解决方案。
【7月更文挑战第3天】PolarDB,阿里云的开源分布式数据库,与微服务相结合,提供灵活扩展和高效管理解决方案。通过数据分片和水平扩展支持微服务弹性,保证高可用性,且兼容MySQL协议,简化集成。示例展示了如何使用Spring Boot配置PolarDB,实现服务动态扩展。PolarDB缓解了微服务数据库挑战,加速了开发部署,为云原生应用奠定基础。
296 3
|
4月前
|
监控 Java 开发者
使用Java开发微服务架构的挑战与解决方案
使用Java开发微服务架构的挑战与解决方案
|
5月前
|
存储 运维 Prometheus
微服务监控:确保分布式系统的可观察性与稳定性
微服务监控:确保分布式系统的可观察性与稳定性
|
11天前
|
设计模式 Java API
微服务架构演变与架构设计深度解析
【11月更文挑战第14天】在当今的IT行业中,微服务架构已经成为构建大型、复杂系统的重要范式。本文将从微服务架构的背景、业务场景、功能点、底层原理、实战、设计模式等多个方面进行深度解析,并结合京东电商的案例,探讨微服务架构在实际应用中的实施与效果。
55 6
|
11天前
|
设计模式 Java API
微服务架构演变与架构设计深度解析
【11月更文挑战第14天】在当今的IT行业中,微服务架构已经成为构建大型、复杂系统的重要范式。本文将从微服务架构的背景、业务场景、功能点、底层原理、实战、设计模式等多个方面进行深度解析,并结合京东电商的案例,探讨微服务架构在实际应用中的实施与效果。
28 1