ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

服务过载保护设计与实施

2021-10-08 11:32:18  阅读:147  来源: 互联网

标签:服务 队列 缓冲 过载 业务 保护 熔断 设计


一、概述

1.1 背景

过载保护是微服务系统无法绕过的技术难题,本文对过载保护的原因、解决方案、实施与测试闭环进行全流程的研究。

1.2 过载分析

过载后如果不进行保护,会导致资源耗尽,进而导致雪崩。过载有很多原因,大致如下:

(1)资源不足,例如cpu、内存、io、存储空间、PID不足;

(2)设计缺陷,例如代码逻辑问题导致处理效率低;

(3)几率性业务重合,例如很多高io业务集中到一个节点上;

(4)用户侧突发压力,例如大量用户在同一时间使用相同功能;

(5)异常业务场景压力增加,例如补偿类的业务造成双倍压力,清理策略失效导致文件量激增;

(6)下游服务异常导致上游业务阻塞,例如网络/存储io缓慢导致上游业务压力变大;

1.3 现状

从软件外部故障和系统测试故障分析,因过载导致的故障占了很大比例,可以说过载是无法避免的问题。本文不讨论业务逻辑,仅讨论的是过载本身的通用解决方案。

二、解决方案

下图是过载保护的几种手段,第1种是通过提高服务能力解决压力不够的问题;第2/3/4种都属于服务降级,即牺牲一部分服务能力;第5种熔断是为了防止压力传导(同时也能防止故障传导);三者之间是不冲突的。

 

 

2.1 增加资源

当发生过载时,首先考虑的是通过增加资源,这样做可以提高服务能力,但也面临很多问题:

(1)资源投入增大,如果是突发压力,会使资源平均使用率下降;

(2)伸展之后还要考虑收缩;

(3)弹缩时机和业务行为强相关,策略不好选择,容易导致延迟伸缩和误判;

(4)能力有上限。

2.2 服务降级

当发生过载之后,服务降级是最经济、高效的手段,可以有效避免服务完全不可用和雪崩,利用有限的资源提供最大的服务能力。

服务降级有很多策略、方法,主要包含如下三种:

1、关闭非核心业务

在资源有效的情况下,保留核心业务、关闭非核心业务是一种常用手段,这种方法很合理,但是实施比较复杂,一方面要提前识别哪些是核心业务、哪些是非核心业务,另一方面,不好评估关闭非核心业务会降低多少压力,以及何时恢复非核心业务。因此关闭非核心业务经常使用手动方式,手动埋点、手动打开/关闭开关。

2、限流

微服务架构下很多服务都是单一功能,不适合关闭非核心业务,因此限流成为主流方法。设置一个线程池/消息队列,超出队列直接拒绝,从而减轻服务的压力。

在实际项目程中,为了应对突发压力,往往会在执行队列的基础上再增加一个缓冲队列,超出执行队列后先放入缓冲队列,少量突发压力会先放入缓冲队列,缓冲队列也满了才会拒绝。

3、降低一致性

降低一致性是一种特殊的服务降级方法,方式有很多(包括上面的缓冲队列也是其中一种)。

(1)同步改为异步,强一致性改为最终一致性

这里主要指请求方的同步改异步,请求发出去之后,等待时间T之后如果没有收到返回值,则不再等待,并给用户返回“请求已经提交,由于系统繁忙,需要排队执行,请勿重复操作。”

这种方式实时性得不到保障,一致性也是通过事务完整性来保障的,不适用所有业务,需要根据实际业务情况选择。

异步只能解决突发压力增加,如果长时间压力大,下游任务依然会积压,最终无法执行成功。并且,如果实现最终一致性,任务失败后会做重试,重试本身又会增加系统压力。

(2)增加缓冲队列

缓冲队列主要用来应对突发压力,当执行队列满了之后,先把请求存入缓存队列。缓冲队列只是“权宜”之计,超出队列的请求依然要进行限流。实际运用中,缓冲队列和限流是不冲突的。

缓冲队列一般使用FIFO的方式进行存取。缓冲队列设置太短起不到很好的效果,会很快充满。设置过长,又会导致部分请求等待时间过长,这些请求执行完成返回给上游时已经超时,上游服务认为这是无效请求(此情况只会出现在上游是同步请求的场景)。这种情况持续一段时间后,每个请求都会超时。因此队列的长度设计要适中,还要考虑实际业务规律。

(3)多副本强一致性,改为主用同步、备用异步

这是一种特殊场景。

根据CAP原则,一致性、可用性、分区数三者必须牺牲一个,在满足CP的业务场景下,除了可用性下降之外,还会导致响应时间增加、对底层压力贡献增加,这时可以通过策略修改一致性,修改为主用同步、备用异步。

总结:降低一致性的三种方式都是为了解决突发压力,第二种方法是常用方法,第一种方法可以和第二种方法配合使用,第一种方法适用范围有限,要根据实际业务决定是否采用。

2.3 熔断

 

 

如上图所示,服务A向服务B发请求,当请求出现大量超时、失败、拒绝时,上游服务A应该停止发送请求,这种行为称为熔断。熔断可以减少对下游施加的压力,也可以防止下游故障向上游传导。

不难看出,服务降级是指当服务压力过大时,本服务通过减少工作量来降低压力,而熔断是通过减少无效请求来降低下游压力,二者的区别主要是实施对象不一样。

三、落地

下图为闭环流程:

 

 

先由项目架构师给出统一的设计原则,然后由产品架构师进行设计、DEV进行开发、测试人员进行测试,然后进行迭代改进。

3.1 设计原则

通过前面的分析,我们对设计原则给出如下使用建议:

1、有性能风险的服务,必须要有弹性,支持垂直或水平弹缩。(现状:水平弹缩目前失效性不满足要求,垂直弹缩场景java微服务的内存无法收缩。)

2、有性能风险的服务,必须要有服务降级能力,关闭非核心业务和限流二选一,降低一致性建议选用缓冲队列,队列长度设置适中,同步/异步要根据实际业务需求选择。(现状:目前没发现关闭非核心业务的微服务,部分业务进行了限流,缓冲队列长度未严格要求。)

3、熔断建议全部使用。(现状:目前基本都没使用)

4、注意:开发团队根据以上原则进行方案设计、开发,针对弹缩、限流、熔断等功能,建议从框架给出解决方案,开发团队只需要根据自己的业务特点填写模板参数即可。

3.2 设计

设计阶段需要给出各项指标,包括弹性伸缩的阈值、弹性伸缩的时间指标、业务并发度指标、缓冲队列长度、熔断阈值和熔断检测周期。这些指标是开发的依据,也是测试的依据。

3.3 开发

根据设计进行开发。

3.4 测试分析

根据4.2设计的进行测试验证,验证既要包含功能是否实现,又要包含效率是否达成。

1、弹性能力验证

(1)垂直弹缩,验证业务闲时资源资源使用率不超过request,忙时超过request但达不到limit。

(2)水平弹缩,验证点是是否能弹、是否能缩,以及时效性是否满足指标要求

2、并发度验证

白盒测试主要在FT覆盖,通过打桩的方式对执行队列和缓冲队列进行压测。

黑盒测试是从业务视角看,执行队列和缓冲队列是无法区分的,可以逐渐增加并发度,看最大并发度是多少。

并发度测试的时候,还要关注①在过负荷的时候是否会限流;②进入队列的任务是否能够全部成功;③长时间过负荷测试服务是否会崩溃。

3、熔断功能验证

熔断的测试方式包含几部分:

(1)下游挂了之后,上游请求一直失败,上游服务是否会熔断;

(2)上游请求超时,是否会熔断;

(3)熔断开启状态,在下游恢复之后,能不能通过有效的检测机制恢复上游业务。

3.5 测试设计与测试用例

1、前端接口级过载测试

针对微服务接口级的测试,要设计相应的压力测试,测试标准参考为3.4测试分析。

2、后端指标类过载测试

针对指标文档中的高并发类指标,后端设计相应的业务并发测试,参考3.4测试分析的第2节并发度验证。

标签:服务,队列,缓冲,过载,业务,保护,熔断,设计
来源: https://www.cnblogs.com/sufuplus/p/15378899.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有