返回顶部
r

rate-limiting速率限制

Rate limiting algorithms, implementation strategies, HTTP conventions, tiered limits, distributed patterns, and client-side handling. Use when protecting APIs from abuse, implementing usage tiers, or configuring gateway-level throttling.

作者: admin | 来源: ClawHub
源自
ClawHub
版本
V 1.0.0
安全检测
已通过
1,756
下载量
免费
免费
0
收藏
概述
安装方式
版本历史

rate-limiting

速率限制模式

算法

算法准确性突发处理最佳适用场景
令牌桶允许受控突发API速率限制、流量整形
漏桶
高 | 完全平滑突发 | 稳定速率处理、队列 | | 固定窗口 | 低 | 允许边缘突发(2倍) | 简单用例、原型开发 | | 滑动窗口日志 | 非常高 | 精确控制 | 严格合规、计费关键场景 | | 滑动窗口计数器 | 高 | 良好近似 | 生产环境API — 最佳权衡 |

固定窗口问题: 用户在11:59发送完整限额请求,又在12:01再次发送,导致有效速率翻倍。滑动窗口可解决此问题。

令牌桶

桶内最多容纳一定数量的令牌。令牌以固定速率补充。每个请求消耗一个令牌。

python
class TokenBucket:
def init(self, capacity: int, refill_rate: float):
self.capacity = capacity
self.tokens = capacity
self.refillrate = refillrate # 每秒令牌数
self.last_refill = time.monotonic()

def allow(self) -> bool:
now = time.monotonic()
elapsed = now - self.last_refill
self.tokens = min(self.capacity, self.tokens + elapsed * self.refill_rate)
self.last_refill = now
if self.tokens >= 1:
self.tokens -= 1
return True
return False

滑动窗口计数器

固定窗口和滑动窗口日志的混合方案——根据重叠百分比对前一个窗口的计数进行加权:

python
def slidingwindowallow(key: str, limit: int, window_sec: int) -> bool:
now = time.time()
currentwindow = int(now // windowsec)
positioninwindow = (now % windowsec) / windowsec

prevcount = getcount(key, current_window - 1)
currcount = getcount(key, current_window)

estimated = prevcount * (1 - positioninwindow) + currcount
if estimated >= limit:
return False
incrementcount(key, currentwindow)
return True



实现方案


方案范围最佳适用场景
内存中单服务器零延迟、无依赖
Redis(INCR + EXPIRE)
分布式 | 多实例部署 |
| API网关 | 边缘 | 无需编码、内置仪表盘 |
| 中间件 | 按服务 | 细粒度按用户/端点控制 |

使用网关级限制作为外层防御 + 应用级限制实现细粒度控制。



HTTP头部

始终返回速率限制信息,即使请求成功:

RateLimit-Limit: 1000
RateLimit-Remaining: 742
RateLimit-Reset: 1625097600
Retry-After: 30

头部何时包含
RateLimit-Limit每次响应
RateLimit-Remaining
每次响应 | | RateLimit-Reset | 每次响应 | | Retry-After | 仅429响应 |

429响应体

json
{
error: {
code: ratelimitexceeded,
message: 超出速率限制。每小时最多1000次请求。,
retry_after: 30,
limit: 1000,
reset_at: 2025-07-01T12:00:00Z
}
}

切勿对速率限制返回500或503——429才是正确的状态码。



速率限制层级

在多个粒度上应用限制:

范围示例限制目的
按IP客户端IP100次请求/分钟滥用防护
按用户
用户ID | 1000次请求/小时 | 公平使用 |
| 按API密钥 | API密钥 | 5000次请求/小时 | 服务间通信 |
| 按端点 | 路由+密钥 | 60次请求/分钟(/search) | 保护昂贵操作 |

分层定价:

层级速率限制突发费用
免费100次请求/小时10$0
专业版
5,000次请求/小时 | 100 | $49/月 |
| 企业版 | 100,000次请求/小时 | 2,000 | 定制 |

从最具体到最不具体进行评估:按端点 > 按用户 > 按IP。



分布式速率限制

基于Redis的模式,实现跨实例的一致限制:

python
def redisratelimit(redis, key: str, limit: int, window: int) -> bool:
pipe = redis.pipeline()
now = time.time()
window_key = frl:{key}:{int(now // window)}
pipe.incr(window_key)
pipe.expire(window_key, window * 2)
results = pipe.execute()
return results[0] <= limit

原子Lua脚本(防止竞态条件):

lua
local key = KEYS[1]
local limit = tonumber(ARGV[1])
local window = tonumber(ARGV[2])
local current = redis.call(INCR, key)
if current == 1 then
redis.call(EXPIRE, key, window)
end
return current <= limit and 1 or 0

切勿先执行GET再执行SET——间隔会导致计数溢出。



API网关配置

NGINX:

nginx
http {
limitreqzone $binaryremoteaddr zone=api:10m rate=10r/s;
server {
location /api/ {
limit_req zone=api burst=20 nodelay;
limitreqstatus 429;
}
}
}

Kong:

yaml
plugins:
- name: rate-limiting
config:
minute: 60
hour: 1000
policy: redis
redis_host: redis.internal



客户端处理

客户端必须优雅地处理429:

typescript
async function fetchWithRetry(url: string, maxRetries = 3): Promise {
for (let attempt = 0; attempt < maxRetries; attempt++) {
const res = await fetch(url);
if (res.status !== 429) return res;

const retryAfter = res.headers.get(Retry-After);
const delay = retryAfter
? parseInt(retryAfter, 10) * 1000
: Math.min(1000 2 * attempt, 30000);
await new Promise(r => setTimeout(r, delay));
}
throw new Error(重试后仍超出速率限制);
}

  • - 始终尊重Retry-After(若存在)
  • 若不存在,使用带抖动的指数退避
  • 对批量操作实现请求排队

监控

跟踪以下指标:

  • - 速率限制命中率 — 返回429的请求百分比(持续超过5%则告警)
  • 接近限制警告 — 剩余额度低于限制10%的请求
  • 最高违规者 — 最频繁触发限制的键/IP
  • 限制余量 — 正常流量距离上限的接近程度
  • 误报 — 被速率限制的合法用户

反模式

反模式修复方法
仅应用层限制始终结合基础设施级限制
无重试指导
始终在429响应中包含Retry-After头部 | | 限制不一致 | 同一端点、跨服务使用相同限制 | | 无突发配额 | 允许合法流量受控突发 | | 静默丢弃 | 始终返回429,以便客户端区分错误 | | 全局单一计数器 | 按端点计数器保护昂贵操作 | | 硬编码限制 | 使用配置,而非代码常量 |

绝对禁止

  1. 1. 绝对不要对健康检查端点进行速率限制 — 监控系统会误报
  2. 绝对不要仅使用客户端提供的标识符作为速率限制键 — 极易被伪造
  3. 速率限制时绝对不要返回200 OK — 客户端必须知道被限流
  4. 绝对不要未测量实际流量就设置限制 — 你会阻挡合法用户,或设置过高而无效
  5. 绝对不要跨不相关租户共享计数器 — 噪声邻居问题
  6. 绝对不要跳过内部API的速率限制 — 行为异常的内部服务可能拖垮

标签

skill ai

通过对话安装

该技能支持在以下平台通过对话安装:

OpenClaw WorkBuddy QClaw Kimi Claude

方式一:安装 SkillHub 和技能

帮我安装 SkillHub 和 api-rate-limiting-1776419943 技能

方式二:设置 SkillHub 为优先技能安装源

设置 SkillHub 为我的优先技能安装源,然后帮我安装 api-rate-limiting-1776419943 技能

通过命令行安装

skillhub install api-rate-limiting-1776419943

下载

⬇ 下载 rate-limiting v1.0.0(免费)

文件大小: 5.04 KB | 发布时间: 2026-4-17 19:42

v1.0.0 最新 2026-4-17 19:42
- Initial release featuring comprehensive documentation on rate limiting algorithms, implementation strategies, HTTP conventions, tiered limits, distributed patterns, and client-side handling.
- Provides practical code samples for Token Bucket, Sliding Window Counter, Redis-based distributed rate limiting (Python and Lua), and API gateway configuration (NGINX, Kong).
- Details recommended HTTP headers and response structures for communicating rate limits and 429 errors.
- Covers best practices, anti-patterns, and critical "never do" guidelines for robust API rate limiting.
- Includes monitoring recommendations and client retry logic examples.

Archiver·手机版·闲社网·闲社论坛·羊毛社区· 多链控股集团有限公司 · 苏ICP备2025199260号-1

Powered by Discuz! X5.0   © 2024-2025 闲社网·线报更新论坛·羊毛分享社区·http://xianshe.com

p2p_official_large
返回顶部