可通过limit_req_zone配合$request_uri和map实现特定静态文件的独立限流:先用map将目标URI映射为固定key(如"favicon"),再以该key定义限流区域,最后在对应location中用limit_req引用并设置burst/nodelay参数,从而精准控制/favicon.ico等热点资源的请求速率。

可以通过 limit_req_zone 指令配合 $request_uri 变量,对高频访问的特定静态文件(如 /favicon.ico、/robots.txt、某张热点图片)做独立限流,避免其耗尽连接或带宽资源。
定义针对 URI 的限流区域
在 http 块中定义一个以 $request_uri 为键的限流区域,注意需用 map 预筛选目标 URI,避免为所有请求都建桶:
map $request_uri $limit_key {
default "";
~*^/favicon\.ico$ "favicon";
~*^/static/cover\.jpg$ "cover_jpg";
~*^/api/v1/health$ "health_check";
}
limit_req_zone $limit_key zone=uri_limit:10m rate=5r/s;
-
map将匹配到的目标 URI 映射为固定字符串(如"favicon"),未匹配则为空字符串 —— 空键不会被limit_req_zone记录,不占用槽位 -
zone=uri_limit:10m分配 10MB 内存,足够支撑数万个不同 key(但此处实际只有几个 key) -
rate=5r/s表示每个匹配的 URI 最多每秒处理 5 个请求;若需更严格,可设为1r/s或启用突发(burst=2 nodelay)
在 location 中启用限流
在对应静态资源的 location 块中引用该 zone,并配置拒绝行为:
location = /favicon.ico {
limit_req zone=uri_limit burst=3 nodelay;
alias /var/www/static/favicon.ico;
}
-
limit_req必须放在具体location内,不能只靠全局server块生效 -
burst=3允许短时突增 3 个请求(例如页面加载触发多个 favicon 请求),nodelay表示这 3 个立即放行,不排队;若去除此参数,则按速率匀速释放 - 建议搭配
limit_req_status 429和自定义错误页,让客户端明确感知被限
注意 URI 匹配的精确性与大小写
$request_uri 包含完整原始路径(含查询参数),且区分大小写。若需忽略参数或统一大小写,需预处理:
- 如要限制
/logo.png?ver=2和/logo.png?ver=3视为同一资源,改用$uri(不含 query)变量:map $uri $limit_key { ... } - 如资源路径可能有大写(如
/IMG/LOGO.PNG),可用map的~*(忽略大小写)正则,或先用perl_set转小写(较重,一般不推荐) - 避免直接用
$request_uri匹配带动态参数的路径(如/file?id=123),否则每个 id 都生成独立 key,导致内存暴涨
验证与调试技巧
启用后可通过日志和响应头确认是否生效:
- 在
log_format中加入$limit_key和$request_time,观察哪些 URI 触发了限流 - 检查响应头:被限流请求会返回
X-RateLimit-Limit(Nginx Plus)或自定义头;开源版可加add_header X-Limit-Status $limit_key;辅助判断 - 用
ab或wrk对单个 URI 压测(如wrk -t2 -c10 -d5s http://host/favicon.ico),观察 429 比例是否符合预期










