理解常见算法的突发能力、精度和分布式实现成本。
图:组合多个限流维度保护系统容量,同时降低共享 IP 与账号锁定误伤;点击查看原图。
核心思路
令牌桶允许有限突发,适合 API 网关;滑动窗口更直观但存储成本更高。限流维度可以是用户、租户、接口或组合键。
落地步骤
返回明确的剩余额度与重试时间。系统过载时限流要与排队、熔断和降级协同。
验证清单
实施后不要只确认“能运行”,还应检查错误率、延迟、资源占用和异常路径。把验证命令、预期结果和回滚方式写进变更记录,后续维护会轻松很多。
小结
好的工程实践不是堆叠工具,而是用清晰边界、可观察结果和可逆变更降低长期成本。先解决最重要的问题,再逐步自动化。
可执行实践
先确定维度、窗口、配额和突发策略。令牌桶适合允许突发,滑动窗口更精确但成本更高;分布式实现用原子脚本或网关能力。
验证与退出条件
返回 429、Retry-After 和剩余额度,演练存储不可用时采用 fail-open 还是 fail-closed。限流与排队、熔断、降级一起压测。
实践场景
以“为公开 API 设置分层限流”为例。实施前先保存当前版本、配置和关键指标基线,写明成功条件与停止条件;涉及生产数据或外部写入时,先在隔离环境验证。
分步实施
在入口按身份和接口执行令牌桶,关键下游再设并发保护;返回明确重试提示,对不同租户设置公平配额。每完成一步都记录可观察结果,不把命令返回零等同于业务正确。
故障演练
测试突发流量、持续超额、分布式节点时钟差和存储不可用,明确限流组件故障时开放还是关闭。演练应使用可清理的测试数据,并验证告警、日志和恢复路径,而不只是确认系统最终又能访问。
观测与回滚
观察拒绝率、下游饱和度与误伤;阈值先灰度,误伤升高立即恢复旧策略。变更单中应写清负责人、观察窗口、阈值和回滚触发器,避免故障发生后再临时争论。
完成后把使用的版本、关键命令、观测窗口和结果写入变更记录。没有验证证据的“已完成”不能作为上线结论。
第二轮实践复核
可复用交付物: 限流决策表、租户配额和降级开关。复用时先固定软件版本、依赖锁文件、测试数据规模和运行环境;文章中的命令包含占位符,必须替换成自己的非生产目标后再执行。
最低验证: 回放突发与持续流量,核对允许量、拒绝量和下游并发上限
执行记录要保存命令、退出码、关键输出、观察窗口和回滚结果。若验证会产生写入,先使用隔离环境或 dry-run;任何失败都不能通过扩大权限、关闭校验或跳过测试来“解决”。
完整实战:登录接口的分层限流
登录限流既要保护服务,也要避免攻击者通过锁定某个账号阻止真实用户登录。单一 IP 限制会误伤公司出口和移动网络,单一账号限制又容易被用来拒绝服务,因此组合多个低基数字段:
| 层级 | 示例键 | 作用 | 超限后的动作 |
|---|---|---|---|
| 边缘 | IP / 网段 | 吸收明显洪峰 | 短时拒绝或挑战 |
| 接口 | 租户 + 路由 | 保护服务总容量 | 429 + 合理退避 |
| 账号 | 账号摘要 | 限制撞库 | 渐进延迟、二次验证 |
| 全局 | 集群容量 | 防止依赖雪崩 | 负载削减、保留关键流量 |
不要把原始邮箱、手机号作为监控标签或共享存储键;先规范化后使用带密钥的摘要,并限制保留期。
令牌桶的原子状态转换
每个键保存剩余令牌和上次补充时间。一次请求到达时先按经过时间补充,再判断是否足够扣减;读取、计算和写回必须原子完成,否则并发请求会突破限制。伪代码如下:
1 | elapsed = max(0, now - last_refill) |
分布式实现需要明确时钟来源、状态分片、热点键和存储故障策略。安全敏感入口通常偏向 fail-closed,但健康检查、内部恢复流量可能需要独立配额,不能在限流存储故障时一起被堵死。
容量与公平性验证
用真实请求成本做权重:一次导出可能等于数十次查询。压测包含稳定流量、突发流量、单热点账号、多 NAT 用户和存储延迟。验收不仅看总 QPS,还看允许率、误伤率、P95 延迟、限流存储错误和不同租户的公平性。
客户端收到 429 后应遵循 Retry-After 并加入抖动;服务端不能让所有客户端在整秒边界同时重试。上线先以只观测模式计算“本应拒绝”的请求,再小比例执行。误伤越线时回退规则或提高容量,不要直接关闭所有保护;保留边缘与全局兜底层。
一手资料
资料与版本边界复核日期:2026-08-22。工具行为可能演进,实施前以锁定版本对应的官方文档为准。
评论