四种常见限流算法有什么区别
一、限流要解决的核心问题
限流的本质是保护系统的处理容量不被超出。任何系统的吞吐都有上限,超过上限的请求如果全部放行,结果不是请求变慢,而是系统崩溃,所有请求一起失败。限流通过拒绝或延迟部分请求,换取整体可用。
不同算法的差异体现在三个方面:对突发流量的容忍度、流量的平滑程度、实现的复杂度。
二、固定窗口:简单但有临界问题
固定窗口算法按固定时间周期计数,例如每秒最多 100 个请求,周期结束计数清零。实现最简单,但存在临界问题:在窗口边界附近,可能短时间内放入两倍阈值的流量。比如第一秒的最后时刻进来 100 个,第二秒的开始时刻又进来 100 个,实际 1 毫秒内通过了 200 个请求。
对精度要求不高的场景可以使用,但不能用于需要严格控制瞬时流量的地方。
三、滑动窗口:更精确但成本更高
滑动窗口把大窗口切成多个小格子,统计最近一个完整滑动周期内的请求数。窗口边界随时间滑动,避免了固定窗口的临界突刺。
代价是需要维护更多状态,格子的数量决定精度和内存开销。格子越细越精确,实现成本越高。滑动窗口适合对限流精度有要求、请求量相对可控的场景。
四、漏桶:强制平滑输出
漏桶算法把请求放入一个固定容量的桶中,以恒定速率流出处理。无论进入的流量多么突发,流出的速度始终平稳。桶满后,新请求被拒绝或排队。
漏桶的特点是输出绝对平滑,适合保护对流量波动敏感的下游,例如支付网关、第三方接口。代价是无法应对合理突发,短时高峰即使系统有能力处理,也会被强制排队,增加延迟。
五、令牌桶:允许受控突发
令牌桶以恒定速率向桶中放入令牌,请求消耗令牌才能通过。桶中积攒的令牌允许一定程度的突发流量,突发量由桶容量决定,长期平均速率由放令牌速度决定。
令牌桶兼顾了限流和突发容忍,是应用最广泛的算法。大多数网关和限流组件的默认实现都是令牌桶或其变种。选择桶容量和放令牌速率时,需要分别对应系统的瞬时承受能力和持续承受能力。
六、分布式限流的额外问题
单机限流只保护单实例,集群环境下需要分布式限流。集中式方案借助 Redis 等共享存储计数,精度高但引入网络开销和单点依赖。分布式方案把总配额分配到各节点本地执行,性能好但精度受节点数变化影响。
实际系统中常见做法是分层限流:接入层做粗粒度的全局限流,服务内部做单机限流兜底。两层配合,比任何单一方案都更可靠。
七、总结
固定窗口简单但有突刺,滑动窗口精确但成本高,漏桶平滑但不容忍突发,令牌桶均衡但参数需要仔细调校。选择限流算法时,先明确要保护的是持续容量还是瞬时容量,再确认被保护对象能否接受突发。限流不是参数越小越安全,误杀正常流量同样是事故。
- 点赞
- 收藏
- 关注作者
评论(0)