一、限流基础概念
1.1 什么是限流
限流(Rate Limiting / Throttling)是一种通过控制单位时间内允许通过的请求数量,来保护系统不被突发流量冲垮的防御手段。它本质上是一个流量整形过程:当请求速率超过预设阈值时,多余的请求会被排队等待、降级处理或直接拒绝。
核心思想:与其让系统在过载时崩溃,不如在接近极限时主动拒绝一部分请求,保证核心服务的可用性。
1.2 为什么需要限流
在微服务架构和高并发场景下,限流是系统稳定性的最后一道防线。以下四个场景最能说明其必要性:
| 场景 | 问题描述 | 无限流的后果 |
|---|---|---|
| 突发流量 | 秒杀、热点新闻、大促活动瞬间涌入大量请求 | 数据库连接池耗尽,服务雪崩 |
| 恶意攻击 | 爬虫、CC 攻击、接口被脚本高频调用 | 带宽占满,CPU 飙升,正常用户无法访问 |
| 后端资源瓶颈 | 数据库连接数、第三方 API 调用配额有限 | 连接超时、熔断、上游服务被拖垮 |
| 成本控制 | 云服务按调用量计费,无限制调用导致账单失控 | 运营成本急剧上升,超出预算 |
1.3 常见限流算法简介
业界主流限流算法有三种:令牌桶、漏桶和计数器。它们各有适用场景,也是后续 Lua 脚本实现的基础。
1.3.1 令牌桶算法(Token Bucket)
令牌桶以固定速率向桶中放入令牌,每个请求必须获取一个令牌才能被处理。桶有容量上限,允许一定程度的突发流量。
- 关键参数:令牌生成速率
r(个/秒)、桶容量b(最大令牌数) - 优点:允许突发,平滑流量,实现简单
- 缺点:需要维护令牌生成定时器,分布式场景下需同步
- 典型应用:Guava RateLimiter、Nginx 限流模块
1.3.2 漏桶算法(Leaky Bucket)
漏桶将请求视为水滴,以固定速率从桶底漏出处理。桶有容量上限,超出容量的请求直接溢出丢弃。它强制输出速率恒定,不允许突发。
- 关键参数:漏出速率
r(请求/秒)、桶容量b(最大排队数) - 优点:输出流量绝对平滑,适合保护下游脆弱系统
- 缺点:无法应对突发流量,即使系统有空闲资源也必须等待
- 典型应用:流量整形、消息队列削峰填谷
1.3.3 计数器算法(Counter / Fixed Window)
计数器将时间划分为固定窗口(如 1 秒),每个窗口内维护一个计数器,请求到达时计数器加 1,超过阈值则拒绝。窗口结束时计数器重置。
- 关键参数:窗口大小
w(秒)、窗口内最大请求数n - 优点:实现极其简单,内存占用极低
- 缺点:存在临界突变问题——窗口边界处可能出现双倍流量
- 典型应用:简单 API 限流、IP 黑名单、登录频率限制
临界突变问题示例:假设限流规则为 1 秒 10 次。如果在第 1 秒的最后 100ms 内通过 10 次请求,紧接着第 2 秒的前 100ms 内又通过 10 次请求,则实际 200ms 内通过了 20 次请求,完全绕过了限流。滑动窗口算法可以解决此问题。
1.4 三种算法对比
| 对比维度 | 令牌桶 | 漏桶 | 计数器 |
|---|---|---|---|
| 输出速率 | 允许突发,平均速率受控 | 绝对恒定 | 窗口内允许突发 |
| 实现复杂度 | 中等(需维护令牌生成) | 中等(需维护漏出队列) | 简单(仅计数器 + 时间窗口) |
| 内存开销 | 低(仅令牌数 + 时间戳) | 低(仅队列长度 + 时间戳) | 极低(仅计数器 + 窗口边界) |
| 临界突变风险 | 无 | 无 | 有(固定窗口边界) |
| 适用场景 | 通用限流,允许短时突发 | 下游脆弱,需绝对平滑 | 简单场景,对精度要求不高 |
| Redis 实现难度 | 中等(Lua 脚本) | 中等(Lua 脚本 + 队列) | 简单(INCR + EXPIRE) |
1.5 限流位置与粒度
在实际系统中,限流可以部署在多个层级:
- 网关层:Nginx + Lua(OpenResty)、Kong、Spring Cloud Gateway——全局流量入口
- 应用层:拦截器、AOP 切面、中间件——按接口/用户/IP 精细化限流
- 数据层:数据库连接池、缓存访问层——保护后端存储
限流粒度通常分为:
| 粒度 | 示例 | 典型场景 |
|---|---|---|
| 全局限流 | 整个 API 网关每秒 10000 次 | 防止整体过载 |
| 接口级限流 | /order/create 每秒 500 次 | 保护核心写接口 |
| 用户级限流 | 每个 user_id 每分钟 60 次 | 防止单个用户刷接口 |
| IP 级限流 | 每个源 IP 每秒 20 次 | 防爬虫、防 CC 攻击 |
课程预告:本章后续将使用 Lua 脚本在 Redis 中实现上述三种算法,并结合缓存保护策略,构建生产级限流方案。令牌桶和滑动窗口计数器将是重点实现对象。