选型的两个轴线
限流篇过半,算法与部署形态都齐了。选型沿着两个轴线走:算法轴线——突刺容忍度与突发宽容度的取舍;部署轴线——单机(快、粗、各管各)与分布式(准、贵、全局一致)的取舍。先上总表,再按场景对号入座。
| 方案 | 精度 | 突发 | 成本 | 典型实现 |
|---|---|---|---|---|
| 固定窗口 | 边界突刺最坏 2 倍 | 无 | 极低 | Redis INCR、网关初筛 |
| 环形格子滑动窗口 | 误差一格占比 | 无 | 低 | Sentinel 统计结构 |
| ZSET 滑动窗口 | 零误差 | 无 | 高(随流量涨) | Redis ZSET + Lua |
| 漏桶 | 出口绝对匀速 | 排队消化 | 中 | Nginx limit_req |
| 令牌桶 | 速率精确 | 允许攒额度 | 中 | Guava、SCG、Redis Lua |
场景对号入座
入口防刷(IP 维度)→ 固定窗口或网关漏桶:精度要求低,成本要极低,量在百万级。接口总量保护→ 分布式令牌桶:速率精确、允许突发,是通用默认。低频高价值接口(短信、支付)→ ZSET 滑动窗口:量小才养得起零误差。刚性下游(短信通道、第三方支付)→ 漏桶:下游消化力固定,匀速最体贴。单实例自保→ Guava 令牌桶:防本实例对慢下游打满并发。秒杀热点商品→ 令牌桶加热点参数维度:总量之外给爆款单独立账。
503 咖啡馆的完整方案
真实系统从来是混合部署,没有一种算法打天下。老王的活动日方案全景:
| 位置 | 算法 | 阈值 | 工具 |
|---|---|---|---|
| Nginx 入口 | 漏桶(IP 维度) | 单 IP 10 r/s,burst 20 | limit_req |
| SCG 网关 | Redis 令牌桶(路由维度) | 下单 2200 QPS | RequestRateLimiter |
| 订单应用 | Redis 令牌桶(用户维度) | 单用户 1 QPS | 注解切面 + Lua |
| 订单应用 | 热点参数(商品维度) | 单商品 200 QPS | Sentinel |
| 短信出口 | 漏桶(对接通道) | 通道 100 条/秒 | 队列 + 定时消费 |
五道闸四种算法,各守一层各管一维——按位置选算法,按维度分账本,按容量定阈值。
四个常见误区
误区一:一种算法打天下——入口用零误差的 ZSET 养百万成员,业务接口全用固定窗口挨突刺,都是没对号入座。误区二:阈值拍脑袋——「大概 1000 吧」的阈值既挡不住雪崩也误杀正常流量,阈值必须压测拐点说了算(第 2 篇)。误区三:只限流不监控——触发率不上报,限流器成了黑盒,容量恶化与流量异常全靠用户投诉发现。误区四:限流后裸拒绝——返回一个 500 断崖,用户只会疯狂重试,把拒绝变成更大的流量;拒绝必须配降级与友好提示。四条对照着自查,比多加十道闸都管用。
限流篇到此收官。它管住的是进来的流量——但雪崩链里还有另一半:系统作为调用方出去的依赖调用。下游病了还持续叩门,线程一样会被拖死。管出这一半的机制叫熔断器,三态模型的断路哲学,下一篇开讲。
评论 (0)