高可用和稳定性

多副本

  1. 本地缓存多副本
  2. Redis多副本
  3. MySQL多副本
  4. 消息中间件多副本

隔离、限流、熔断和降级

隔离

定义:将系统或资源分割开,在系统发生故障时能限定传播范围和影响范围,即发生故障后不会出现滚雪球效应

  1. 数据隔离
  2. 机器隔离
  3. 线程池隔离:为了某个rpc接口较慢导致线程池打满,为不同的rpc接口提供不同的线程池
  4. 信号量隔离:为了解决线程数过多导致上下文切换开销的大问题,共用线程池但是取线程之前需要获得信号量,信号量达到阈值则无法获取线程

限流

定义:系统的处理能力不能应对外部请求的涂增流量时,为了不让系统崩溃(如线程池资源耗尽),需要采取限流的措施

方式

  1. 技术层面的限流
    限制并发数:比如数据库连接池、线程池、Nginx的limit_conn模块
    限制速率:比如Guava的RateLimiter、Nginx的limit_req模块
  2. 业务层面的限流
    如在秒杀系统中,一个商品的库存只有100件,现在有2万人抢购,没有必要放2万个人进来,只需要放前500个人进来,后面的人直接返回已售完即可。具体实现上,有团队使用Redis,也有团队直接基于Nginx+Lua脚本来实现

限流算法

并发数限制

限制并发数的计算原理很简单,系统只需要维护正在使用的资源数或空闲数,比如数据库的连接数、线程池的线程数

速率限制

  1. 固定窗口计数
  • 方式:
    • 在固定时间区间内统计请求数量
    • 达到阈值后拒绝请求
  • 缺点:
    • 临界点爆发问题,0.99秒1000个请求,1.01秒1000个请求
    • 突刺,0.1处理1000个请求,剩下0.9秒无法处理请求
  1. 滑动窗口计数
  • 方式:
    • 将时间窗口进一步细分为小块(比如1秒->10个0.1秒)
    • 每个小窗口分别计数,滑动加总
  • 优点:缓解临界爆发,流量统计更平滑
  • 缺点:缓解临界爆发,不解决
  1. 滑动时间窗口
  • 方式:
    • 精确记录每次请求的时间戳
    • 每次检查当前时间,除去超过时间范围的请求计数,计算窗口内真实数量
  • 缺点:内存占用高,不适合高并发场景
  1. 漏桶算法
  • 方式:
    • 请求以仁义速度进入系统,被积压放入桶中,即入水速度任意
    • 请求按固定速率处理(出水速率恒定),即出水速度恒定
    • 请求可以缓冲排队,溢出直接丢弃
  • 特点:平滑流量,不能积压太多突发流量
  1. 令牌桶算法
  • 方式:
    • 定时向桶内放入令牌(以固定速率)
    • 每个请求拿一个令牌,拿到才能处理,没有就拒绝或者排队
  • 特点:可以应对突发流量

漏桶算法 vs 令牌桶算法

- 漏桶算法 令牌桶算法
特点 流出速率保持恒定 流入速率保持恒定
用途 类似消息队列,起到了削峰的作用,平滑了突发流入速率 限制的是平均流入速率,可能一段时间没有请求令牌累积,突发流量一瞬间取令牌处理

熔断

定义:当某个服务持续失败或响应异常,系统主动“断开”对它的调用一段时间,避免整个系统雪崩

根据请求失败率做熔断

对于客户端调用的某个服务,如果服务在短时间内大量超时或抛错,则客户端直接开启熔断,也就是不再调用此服务。然后过一段时间,再把熔断打开,如果还不行,则继续开启熔断。这也正是经常提到的“快速失败(Fail Fast)”原则”

根据请求响应时间做熔断

Sentinel 的思路根据请求响应时间做熔断。当资源的平均响应时间超过阈值后,资源进入准降级状态。接下来如果持续进入5个请求,且它们的RT 持续超过该阈值,那么在接下来的时间窗口内,对这个方法的调用都会自动地返回

降级

定义:降级是一种兜底方案,是在系统出故障之后的一个尽力而为的措施。比如电商推荐系统,当宕机时,可以为首页准备一个非个性化的商品列表,甚至一个静态的商品列表

作者

jszero

发布于

2025-05-03

更新于

2025-05-04

许可协议

评论