微服务应用如何实现无损上下线|学习笔记(一)

本文涉及的产品
服务治理 MSE Sentinel/OpenSergo,Agent数量 不受限
注册配置 MSE Nacos/ZooKeeper,118元/月
云原生网关 MSE Higress,422元/月
简介: 快速学习微服务应用如何实现无损上下线

开发者学堂课程【微服务应用如何实现无损上下线:微服务应用如何实现无损上下线】学习笔记,与课程紧密联系,让用户快速学习知识。  

课程地址:https://developer.aliyun.com/learning/course/974/detail/14895


微服务应用如何实现无损上下线

内容介绍

一、应用上下线过程当中出现流量有损的背景原因

二、mse 实现应用发布无损上下线的方案

三、mse 实现应用无损上下线的最佳时间 demo 进行演示

一、应用上下线过程当中出现流量有损的背景原因

1. 应用的事故通常发生在应用上下线的过程中,事故的原因可能是因为研发代码出错,导致上下线的过程中信息系统不可用,但即使代码已经做了很好的检查,实际在应用发布的过程中,还是会出现短暂的服务使用报错或者服务不可用的问题。

原因:在流量高峰的时候,报错会多一点,在流量较小时,报错会少一点,所以很多人选择在应用流量特别小的时候,进行应用发布规避线上的问题。

2.常见的应用在上下线的过程出现这个服务报错的原因

(1)服务无法及时下线:服务下线动作不能被上游的消费应用实时感知,在 SpringCloud 应用 Consumer 感知注册中心服务列表存在延时,导致应用下线后在一段时间内仍然调用下线应用。

(2) 例如:Consumer是通过定时的,默认30秒在中心获取最新的服务实例列表信息,假设提供在 ProviderA 下线的时候,被服务消费者感知到存在一定的延时,在延时期间,如果有流量调用,会通过本地的缓存里面调用服务的列表,这个时候就会出现调用已下线的 ProviderA ,出现流量有损的问题。

(3) 图片1.png

(4) 初始化慢:新启动应用需要进行资源加载,大规模流量直接请求过来,导致刚启动应用被流量击垮!  

例如:

是K8S直部署的一个应用。在另一个版本弹起来时pllot被流量击垮,问题产生的原因是资源初始化慢。  

demo的演示,在第一次调用的时候,因为存在reban核心类的第一次调用,才会进行核心类的初始化。因此第一次调动的延时很长,第一次调用完成之后,后续的调用时间很短,因为存在第一次调用很大的应用初始化时间,因此如果有大量流量之间像刚启动的应用请求,就会出现大量的请求的响应超时。大量的请求的延时阻塞导致刚启动的实例的硬件资源如CPU 、内存等,被消耗殆尽导致刚启动应用被流量击垮。

(3)注册太早:服务存在异步资源加载问题,尽管应用的一些类已经完成了初始化,当服务还未初始化完成就被注册到注册中心,导致响应慢出现请求报错。

(4)发布态与运行态未对齐:使用K8s的滚动发布功能进行应用发布,新应用还未注册到注册中心,老应用实例就被下线,导致无服务可用。

本质:K8s 的滚动发布机制和微服务的应用的生命周期,没有关联关系,K8s 滚动发布,结合就绪探针的机制,能够感知到应用的某个端口启动之后,再进行下批次的应用发布。

对于微服务应用,应用 redio 的就绪状态通常不是应用的某个端口启动就处于就绪状态,而是需要应用自身已经完初始化,并且注册到注册中心,以及能够被上游调用的时候,才处就绪态,可以进行之后的发布。

因此k8s的生命周期与微服务的生命周期没有绑定的关系。因此出现假设应用的某端口已启动,但此时应用没有注册到注册中心,但K8s认为这个应用启动就序,便下线原有的实例,但新的实例也没有上线。因而调用的消费者发现没有可用的实例列表,出现noprovide 的问题。


二、mse 实现应用发布无损上下线的方案

1.无损下线

(1)无损下线背景原因:

服务端:下线动作不能被客户端实时感知,原因为服务端可能已下线,但由于通过新的跳槽时机感知服务端下线的形式会有一定的延时,可能在之后才能感知到服务端下线。

客户端:通过拿取注册中心里面服务列表的方式感知服务端下线,在 SpringCloud 里面默认的拿取动作为30秒一次,因此感知到服务端下线的时间更长,。在真实服务下线到被客户端感知到服务下线的时间内,如果客户端流量比较大,再进行调用,就会出现服务的调用报错。

图片2.png

(2)解决:咨询等待和主动通知的无损下线的方案。首先通过 mse的 java Agent 技术,每一个应用会注入增强,通过自检码的方式增加额外的逻辑,比如说是咨询等待、通知等。

如图所示,例如提供者A,要进行下线时,不会出现没有使用无损下线时马上就下线的情况,会有默认的等待时间。在等待的时间之内,会做一些下线的动作,让上游消费者能够及时感知,避免调用报错。

(3)步骤:

消费者正常调用提供者A,提供者A会在下线之前会通过prestop,实现向注册中心反注册的动作,注册中心能够实时感到提供者A已经下线。

向注册中心进行在反注册之后,提供者A在主动通知的时间之后的等待时间内,会将接收的请求的流量进行记录,并对这些流量的返回值做一些特殊的处理,对流量的发起的消费者,进行主动通知。告诉发送请求的消费者,提供者A已经下线,之后不用调提供者A。收到请求的消费者会把提供者A标记为下线状态,同时,会在注册中心发起拉取服务列表的信息,拉取到最新的服务列表,在下次调用的时不会再调用下线的提供者A,会去调用其他的提供者。

2.无损上线

(1)无损上线原因:

刚启动应用需要一定的初始化时间,但在发布过程中因为流量较大给予初始化时间较短,导致大量的请求来不及初始化,产生比较高的延时,造成请求阻塞,因此应用挤压导致发布的事故。

(2)解决方法:小流量预热

Dubbo 的小流量预热:

小流量预热的效果类似下图所示,正常情况下假设没有小流量预热的实例发布过程中,上线就会接收到正常的Qps值,但经过小流量预热后,应用发布的过程中,接受的流量在预热的周期内缓慢增加,因此通过此机制对刚启动发布的应用进行保护。

图片3.png

(3)原理:

在服务提供端,通过用户配置预热时间,以及权重等参数,通过注册中心被消费者感知,消费者通过预热的附带均衡的算法,实时在调用时刻计算每一个应用的提供者的权重,对于刚启动的应用,它的 StartTime 离 now 比较近,所以分子很小,然最终计算的权重比较小,对于刚启动的应用,所分配的流量就会比较小,然后实现对保护的效果。

(4)Dubbo 的预热并没有解决问题,它是恒定的预热曲线,在使用的过程中,它的普适性不强,对于一些特殊的应用,有时反而会带来问题。

图片4.png

问题:

SpringCloud 应用不能实时感知注册中心实例变化,如何解决因此出现的预热时长低于预期问题?

服务预热如何进行服务预热可视化?

服务预热如何适配云原生应用场景?

Dubbo 采用线性的预热曲线,刚开始应用启动时流量尽可能小,他就要需要把预热的时间设置的比较长,但预热时间长使应用的发布周期变长,会对应用发布的效率造成影响

场景:

启动流量小,预热曲线是线性,预热时长会长,所以设置为9 min

一般滚动发布3批,每批间隔5 min ,批次数1,2,3。

第1批: 0 min ,1个实例预热(流量缓慢增加),5个实例正常(小流量预热,通过负载均衡,把原来要分配给预热实例的多余的流量,均衡到其他的正常或是预热比较久的实例),正常实例能抗住多余流量

第2批: 5 min ,第一个实例是预约9 min ,5 min 时还没结束,所以3个实例预热,3个实例正常,正常实例勉强能抗住多余流量

第3批:10 min ,第一个实例是预约9 min ,所以10 min 时结束,所以5个实例预热,1个实例正常,设置的cpu和内存不是特别大,没法抵挡,原本要分配给这5个预热实例的流量,导致正常机器宕机。

诉求:希望第1 min,流量尽可能小,预热过程能够快速的收敛,可能在第二分钟时马上恢复正常。但是,采用Dubbo的服务预热方法,因为是线性的曲线,无法做到。如果刚开时流量较小,恢复正常的时间就要比较长,基于这个背景,提出基于高阶曲线的可快速收敛预热过程的预热方法。

在 mse 里,提供让用户就是配置一些高级的预热曲线,应用在不同的场景,让所有的应用能够最大限度利用服务预热来对应用进行保护,而不是出现相关分析的问题。

除了对Dubbo的预热进行了改进及产品化以外,在实现无损上线当中的小流量域的过程中,针对 SpringCloud 的应用做了一些处理,或对怎样去实现一个服务域的可视化的能力的增强。

(5)mse 提供的无损上线能力的完整介绍:

第一部分:对于刚启动的应用,有些应用需要资源初始化时间较长,一些连接池需要创建,无损上线的方案通过javaAgent的方式,能够帮助用户进行初始化资源的建立

第二部分:在服务注册过程中有时服务注册太早,应用里面有些服务,需要一些异步的资源加载。未加载完成在线上接收流量,会出现流量阻塞,导致应用宕机。针对doubbo应用和SpringCloud应用都支持来延迟注册的能力解决问题

第三部分:结合K8s就绪检查机制,能够让K8s配置就绪探针与微服务注册完成关联,感知到服务是否注册完成。

第四部分:小流量服务预热,预热模型支持动态调节,支持高阶模型配置,满足更多复杂应用预热场景需求;预热过程支持关联K8sreadiness检查,无缝支持云原生应用发布场景,让服务预热之后,K8s发布之后,就绪检查才会通过。

图片5.png

相关实践学习
通过Ingress进行灰度发布
本场景您将运行一个简单的应用,部署一个新的应用用于新的发布,并通过Ingress能力实现灰度发布。
容器应用与集群管理
欢迎来到《容器应用与集群管理》课程,本课程是“云原生容器Clouder认证“系列中的第二阶段。课程将向您介绍与容器集群相关的概念和技术,这些概念和技术可以帮助您了解阿里云容器服务ACK/ACK Serverless的使用。同时,本课程也会向您介绍可以采取的工具、方法和可操作步骤,以帮助您了解如何基于容器服务ACK Serverless构建和管理企业级应用。 学习完本课程后,您将能够: 掌握容器集群、容器编排的基本概念 掌握Kubernetes的基础概念及核心思想 掌握阿里云容器服务ACK/ACK Serverless概念及使用方法 基于容器服务ACK Serverless搭建和管理企业级网站应用
相关文章
|
9天前
|
存储 JSON 监控
微服务链路追踪原理,一文搞懂!
本文重点讲解微服务链路追踪(Microservices Distributed Tracing),介绍其原理、架构及工作流程。关注【mikechen的互联网架构】,10年+BAT架构经验倾囊相授。
微服务链路追踪原理,一文搞懂!
|
2月前
|
运维 监控 前端开发
微服务灰度发布的底层原理是什么?
微服务灰度发布的底层原理是什么?
49 1
|
监控 负载均衡 前端开发
微服务架构之链路追踪原理
微服务架构是一个分布式架构,它按业务划分服务单元,一个分布式系统往往有很多个服务单元。由于服务单元数量众多,业务的复杂性,如果出现了错误和异常,很难去定位。主要体现在,一个请求可能需要调用很多个服务,而内部服务的调用复杂性,决定了问题难以定位。
590 0
|
消息中间件 缓存 运维
【微服务】如何实现微服务集群的高可靠?
实现微服务高可靠11连问,你能扛住几问?
431 1
【微服务】如何实现微服务集群的高可靠?
|
6月前
|
缓存 负载均衡 Java
大规模 Spring Cloud 微服务无损上下线探索与实践
“从一次常见的发布说起,在云上某个系统应用发布时,重启阶段会导致较大数量的 OpenAPI、上游业务的请求响应时间明显增加甚至超时失败。随着业务的发展,用户数和调用数越来越多,该系统又一直保持一周发布二次的高效迭代频率,发布期间对业务的影响越来越无法接受,微服务下线的治理也就越来越紧迫。”
大规模 Spring Cloud 微服务无损上下线探索与实践
|
Kubernetes 算法 Java
微服务应用如何实现无损上下线|学习笔记(二)
快速学习微服务应用如何实现无损上下线
微服务应用如何实现无损上下线|学习笔记(二)
|
Kubernetes Dubbo 前端开发
在低容错业务场景下落地微服务的实践经验
“健康体检是一个低容错的场景,用户到医院体检,由于 IT 原因导致无法完成预约的项目,会对用户体验造成极大的影响。” ——禾连健康 CTO 邓志豪
在低容错业务场景下落地微服务的实践经验
|
Kubernetes 关系型数据库 微服务
解决微服务架构下流量有损问题的实践和探索
绝⼤多数的软件应⽤⽣产安全事故发⽣在应⽤上下线发布阶段,尽管通过遵守业界约定俗成的可灰度、可观测和可滚回的安全⽣产三板斧,可以最⼤限度的规避发布过程中由于应⽤⾃身代码问题对⽤户造成的影响。但对于⾼并发⼤流量情况下的短时间流量有损问题却仍然⽆法解决。因此,本文将围绕发布过程中如何解决流量有损问题实现应⽤发布过程中的⽆损上下线效果相关内容展开⽅案介绍。
解决微服务架构下流量有损问题的实践和探索
|
缓存 运维 Kubernetes
微服务应用实现无损上下线最佳实践
本文是阿里云微服务引擎MSE在应用发布时提供的无损上下线和服务预热能力最佳实践介绍。
2072 1
|
运维 Java 程序员
进行微服务治理,先要对微服务进行度量(1)
进行微服务治理,先要对微服务进行度量(1)
366 0
进行微服务治理,先要对微服务进行度量(1)
下一篇
无影云桌面