C. 高可用架构 — 限流降级
概述
- 核心思路:优先保证核心业务和优先保证绝大部分用户
- 原因
- 内部原因:程序 bug 导致死循环,某个接口导致数据库慢查询,程序逻辑不完善导致耗尽内存等。
- 外部原因:黑客攻击、促销或者抢购引入了超出平时几倍甚至几十倍的用户,第三方系统大量请求,第三方系统响应缓慢等。
- 过载情况
- 数据中心大量后端任务都处于过载状态
- 数据中心一小部分后端任务处于过载状态
降级
- 方案
- 系统后门降级
- 独立降级系统
- 思路
- 流量抛弃
- 降低特定服务的回复质量
- 禁用特定业务
限流
- 降级是从系统功能优先级的角度考虑如何应对故障,而限流则是从用户访问压力的角度来考虑如何应对故障。限流指只允许系统能够承受的访问量进来,超出系统访问能力的请求将被丢弃。
- 方法
- 基于请求的限流:基于上述的分析,根据阈值来限制访问量的方式更多的适应于业务功能比较简单的系统,例如负载均衡系统、网关系统、抢购系统等。
- 限制总量:限制总量的方式是限制某个指标的累积上限,常见的是限制当前系统服务的用户总量。
- 限制时间量:限制时间量指限制一段时间内某个指标的上限
- 基于资源的限流:基于请求限流是从系统外部考虑的,而基于资源限流是从系统内部考虑的,即:找到系统内部影响性能的关键资源,对其使用上限进行限制。常见的内部资源有:连接数、文件句柄、线程数、请求队列等。
- 基于请求的限流:基于上述的分析,根据阈值来限制访问量的方式更多的适应于业务功能比较简单的系统,例如负载均衡系统、网关系统、抢购系统等。
- 限制层级
- 客户端限流:当客户端从服务端接收到的错误数量增多的时候,自行限制请求速度,限制它自己生成请求的数量
- 优点
- 简单,依赖本地信息做决定
- 优点
- 服务断限流
- 第一类,接入层限流
- Nginx 限流
- API 路由网关模式
- 第二类,应用限流
- 第三类,基础服务限流
- 第一类,接入层限流
- 客户端限流:当客户端从服务端接收到的错误数量增多的时候,自行限制请求速度,限制它自己生成请求的数量
- 其他
- RPC添加属性 — 请求重要性,当过载的时候,按照请求优先级顺序分级拒绝请求,一般在离浏览器或者客户端最近的地方设置优先级
- 最重要的 CRTICIAL_PLUS
- 重要 CRTICIAL
- 可丢弃的 SCHEDDABLE_PLUS
- 可丢弃的 SCHEDDABLE
- 设置请求的截止时间,需要传递截止时间
- 时间太长导致高层级部分由于底层级的问题而持续消耗资源
- 时间太短导致重型请求持续失败
- RPC添加属性 — 请求重要性,当过载的时候,按照请求优先级顺序分级拒绝请求,一般在离浏览器或者客户端最近的地方设置优先级
熔断
- 熔断机制实现的关键是需要有一个统一的 API 调用层,由 API 调用层来进行采样或者统计,如果接口调用散落在代码各处就没法进行统一处理了。
排队
- 排队实际上是限流的一个变种,限流是直接拒绝用户,排队是让用户等待一段时间,全世界最有名的排队当属 12306 网站排队了。排队虽然没有直接拒绝用户,但用户等了很长时间后进入系统,体验并不一定比限流好。
连接造成的负载
- 场景
- 批处理启动的时候,一瞬间会建立大量的连接
- 措施
- 把负载连接传递给其他的数据中心
- 在批处理客户端和后端任务之间,加入一层的批处理代理
重试
- 是否重试:如果底层DB负载太多,直接返回“过载;无须重试”,避免出现重试爆炸
- 如何重试
- 使用随机化,指数型递增的重试周期
- 限制重试次数
- 使用重试预算,比如说每个进程每分钟只允许重试60次
- 从多个视角重新审视该服务,决定是否需要在某个级别上进行重试。对于分布式系统,4个服务,3次重试,可以产生4^3次即64次的请求
- 使用明确的返回代码,同时详细考虑每个错误模式应该如何处理。例如,将可重试错误和不可重试错误分开