Nginx 通过 limit_req_module 实现基于时间窗口的请求速率限制,支持按 IP、用户标识或路径差异化配额,并可排除 OPTIONS 预检请求;需配合后端协同避免错位限流。

Nginx 本身不提供“配额”(如每日/每月调用次数)这类带时间窗口累计的资源计量能力,但它可通过 limit_req_module 模块实现基于时间窗口的请求速率限制,这是生产环境中最常用、最贴近“配额效果”的方案。关键在于合理设计限流粒度、缓冲策略与例外处理。
按客户端 IP 实现基础请求配额
适用于防止单个用户滥用,例如“每分钟最多 60 次请求”:
http {
limit_req_zone $binary_remote_addr zone=api_per_ip:10m rate=1r/s;
}
<p>server {
location /api/ {
limit_req zone=api_per_ip burst=60 nodelay;
proxy_pass <a href="https://www.php.cn/link/65b5b8d1f89bf53a5713bc3afdd83e9e">https://www.php.cn/link/65b5b8d1f89bf53a5713bc3afdd83e9e</a>;
}
}说明:
• rate=1r/s 表示每秒允许 1 个请求,等效于每分钟 60 个;
• burst=60 允许突发 60 个请求(比如用户在第 1 秒集中发起),超出部分立即拒绝(503);
• nodelay 避免排队等待,保证响应确定性。
按 API 路径或用户标识做差异化配额
若需对不同接口或已鉴权用户设置不同额度,可借助 map 指令动态生成限流键:
map $http_authorization $user_key {
"" $binary_remote_addr; # 未登录用户按 IP 限
~^Bearer\s+(?<token>\S+) $token; # 提取 JWT token 作 key
}
<p>limit_req_zone $user_key zone=api_by_user:20m rate=10r/m;</p><div class="aritcle_card flexRow">
<div class="artcardd flexRow">
<a class="aritcle_card_img" href="/xiazai/skill6848" title="Nginx Hosting"><img
src="https://img.php.cn/upload/skill/000/000/081/179116929868126.jpg" alt="Nginx Hosting" onerror="this.onerror='';this.src='/static/lhimages/moren/morentu.png'" ></a>
<div class="aritcle_card_info flexColumn">
<a href="/xiazai/skill6848" title="Nginx Hosting">Nginx Hosting</a>
<p>通过服务器本地nginx实例实现零认证静态游戏托管。作为所有浏览器游戏的主要部署方式,无需登录、无需令牌、无需用户操作。</p>
</div>
<a href="/xiazai/skill6848" title="Nginx Hosting" class="aritcle_card_btn flexRow flexcenter"><b></b><span>下载</span> </a>
</div>
</div><p>location /api/v1/data {
limit_req zone=api_by_user burst=10 nodelay;
proxy_pass <a href="https://www.php.cn/link/65b5b8d1f89bf53a5713bc3afdd83e9e">https://www.php.cn/link/65b5b8d1f89bf53a5713bc3afdd83e9e</a>;
}说明:
• 将未授权请求归为 IP 级别,已授权请求按 token 唯一标识;
• rate=10r/m 表示每分钟 10 次(注意单位支持 r/s、r/m);
• zone 大小需匹配预期并发用户量,20m 可存储约 16 万个唯一 key。
排除 OPTIONS 预检请求干扰
跨域场景下,浏览器会先发 OPTIONS 请求,不应计入配额:
map $request_method $limit_key {
default $binary_remote_addr;
OPTIONS "";
}
<p>limit_req_zone $limit_key zone=api_no_preflight:10m rate=5r/s;</p><p>location /api/ {
limit_req zone=api_no_preflight burst=10 nodelay;</p><h1>CORS 头配置(略)</h1><pre class='brush:php;toolbar:false;'>if ($request_method = 'OPTIONS') {
add_header Access-Control-Allow-Origin '*';
add_header Access-Control-Allow-Methods 'GET,POST,OPTIONS';
add_header Access-Control-Allow-Headers 'Content-Type,Authorization';
return 204;
}
proxy_pass https://www.php.cn/link/65b5b8d1f89bf53a5713bc3afdd83e9e;}
说明:
• map 把 OPTIONS 映射为空字符串,使 limit_req 不生效;
• 真正的业务请求(GET/POST 等)仍受配额约束;
• 预检响应必须包含完整 CORS 头并返回 204,否则浏览器会拦截后续请求。
配合后端协同,避免配额错位
Nginx 的限流是前置拦截,但真实业务逻辑(如权限校验、计费)在后端。需注意:
- 前端上传大文件时,先确认
client_max_body_size是否足够,否则 413 错误早于配额检查发生; - 若后端也做限流(如 Spring Cloud Gateway 或 Redis 计数),Nginx 层应设得稍宽松,避免双重拦截;
- 日志中记录被限流的请求(
limit_req_log_level warn),便于监控和告警。

















