当前位置: 首页 > news >正文

限流算法详解:固定窗口、滑动窗口、令牌桶与漏桶算法全面对比

限流(Rate Limiting)是保障系统稳定性和服务质量的关键机制,尤其在高并发、突发流量、攻击防护等场景中至关重要。

本文将详细介绍四种主流限流算法:

  • 固定窗口(Fixed Window)

  • 滑动窗口(Sliding Window)

  • 令牌桶(Token Bucket)

  • 漏桶算法(Leaky Bucket)

我们将从原理、实现方式、优缺点和适用场景四个维度进行深入分析和对比。


一、固定窗口(Fixed Window)

原理:将时间划分为固定长度窗口,统计每个窗口内的请求数,超过上限则拒绝。

实现方式(常用 Redis INCR + EXPIRE):

key = f"req:{user_id}:{current_minute}"
count = redis.incr(key)
if count == 1:redis.expire(key, 60)
if count > threshold:reject()

优点

  • 实现简单,性能高。

  • Redis 支持天然适配。

缺点

  • 临界突刺问题:在两个窗口交界点,可能放行两倍请求。

适用场景

  • 精度要求不高的接口。

  • 管控类后台系统。


二、滑动窗口(Sliding Window)

1. 滑动日志(Sliding Log)

原理:记录每次请求时间戳,实时清理超出时间窗口的旧请求,判断窗口内数量。

优点

  • 流量限制更精确。

  • 避免突刺。

缺点

  • 需要维护时间戳列表,内存消耗较大。

2. 滑动窗口计数器(Sliding Window Counter)

原理:将一个窗口拆分为多个小窗口,每个子窗口统计请求数,根据时间加权合并。

优点

  • 性能和精度之间较好平衡。

适用场景

  • 高并发、登录、敏感操作等流控要求较高的业务。


三、令牌桶算法(Token Bucket)

原理

  • 系统以固定速率放入“令牌”到桶中;

  • 每次请求需要“取一个令牌”才能通过;

  • 桶容量有限,超过上限的令牌被丢弃;

  • 若桶为空,请求被限流(或排队等)。

示意图

+----------+
| 令牌桶    |
|          |<-- 固定速率生成令牌
|   [ ]    |
+----------+↓请求来取令牌 -> 成功 or 被限流

优点

  • 支持突发流量(令牌可积累)。

  • 灵活控制平均速率与突发能力。

  • Guava / Nginx 都有成熟实现。

缺点

  • 实现较复杂。

  • 依赖精准时间调度。

适用场景

  • 接口限频,突发高并发业务。

  • LLM API 限流 / OpenAI、Stripe 等系统。


四、漏桶算法(Leaky Bucket)

原理

  • 所有请求先进入一个桶中;

  • 桶以固定速率“漏水”处理请求;

  • 桶满时,新请求要么被丢弃,要么排队等待。

示意图

请求 → 桶(队列) → 以恒定速率处理(漏水)↑桶满则拒绝或排队

实现方式

  • 可以用一个队列存储请求;

  • 后台定期以固定速率出队并处理请求。

优点

  • 平滑处理请求流量,保持处理速率稳定。

  • 防止服务被瞬时流量压垮。

缺点

  • 不支持突发流量(桶中积压,排队延迟)。

  • 实现复杂度略高于令牌桶。

适用场景

  • 网关、负载均衡器的请求调度。

  • 强调处理速率恒定的后台任务系统。


五、算法对比总结

特性固定窗口滑动窗口令牌桶漏桶
实现复杂度⭐(简单)⭐⭐(中等)⭐⭐⭐(中高)⭐⭐(中等)
限流精度中等
是否支持突发请求
是否平滑
是否常用✅(Redis)✅(Sentinel)✅(Guava、Nginx)✅(调度系统)

六、实战建议

  • 简单限流场景(如后台管理):使用 固定窗口 + Redis 即可。

  • 高并发接口限频:推荐 滑动窗口令牌桶,后者更适合突发请求。

  • 需要平滑处理队列任务:选择 漏桶算法


七、结语

限流并不是一刀切的“阻止请求”,而是为系统争取喘息空间。不同的限流算法背后体现的是不同的设计哲学与业务权衡。

选对限流算法,既可以保护系统,又能优化用户体验。

http://www.dtcms.com/a/307130.html

相关文章:

  • P1036 [NOIP 2002 普及组] 选数
  • 结合C++红黑树与AI人工智能的应用
  • Linux 系统日志管理与时钟同步实用指南
  • TCP和UDP编程的主要区别
  • 当人生低谷无人帮助时,如何独自奏响人生乐章
  • Linux系统编程Day1-- Linux系统的概念,主要内容
  • 查看遥控器6通道(以及其他通道)的实际PWM值
  • 洛谷 P1601 A+B Problem(高精)普及-
  • Datawhale AI夏令营 大模型技术task3 稍稍提分
  • 密码学安全性简介
  • LLM—— 基于 MCP 协议(Stdio 模式)的工具调用实践
  • 从一开始的网络攻防(十三):WAF入门到上手
  • 疏老师-python训练营-Day30模块和库的导入
  • Mysql事务基础
  • 通俗易懂的解释G1垃圾收集器
  • 学习Markdown
  • vulhub-Thales靶场攻略
  • git的开发流程
  • # C语言:20250730学习(二级指针)
  • OneCode 3.0 快速视图在 DDD 领域模型中的应用研究
  • 「Linux命令基础」管理文件
  • 【动态规划 | 多状态问题】动态规划求解多状态问题
  • 7. 传输层协议 TCP
  • 低速信号设计之 MDIO 篇
  • 7.5将模块分离到不同的文件中
  • FastAPI入门:表单数据、表单模型、请求文件、请求表单与文件
  • 电商项目统一认证方案设计与实战
  • 《JWT + OAuth2统一认证授权:企业级单点登录方案》
  • 【硬件-笔试面试题】硬件/电子工程师,笔试面试题-50,(知识点:TCP/IP 模型)
  • NSGA-III(Non-dominated Sorting Genetic Algorithm III)简介