可通过limit_req指令结合map识别设备类型并差异化限流:先用map从user-agent提取mobile/desktop/other三类变量,再为每类定义独立limit_req_zone,最后在location中按变量值选择对应zone限流。

可以通过 limit_req 指令结合 Nginx 的变量(如 $http_user_agent 或自定义设备识别变量)实现按设备类型(PC、移动端、爬虫等)差异化限流。核心在于:先识别设备类型并设为变量,再基于该变量定义不同限流区域(limit_req_zone),最后在 location 中按需应用。
识别设备类型并设置变量
利用 map 指令从 User-Agent 提取设备特征,生成可读性强的设备标识变量:
- 匹配常见移动端 UA 关键词(如
Mobile、Android、iPhone),设为mobile - 排除移动端后,再匹配桌面端典型 UA(如
Windows、Mac OS X、Linux、Firefox、Chrome),设为desktop - 其余(含空 UA、疑似爬虫或未知客户端)统一标记为
other
示例配置:
map $http_user_agent $device_type {
default other;
~*[Mm]obile mobile;
~*[Aa]ndroid mobile;
~*[Ii]phone mobile;
~*[Ii]pad mobile;
~*[Ww]indows.*[Nn]t desktop;
~*[Mm]ac\s+[Oo][Ss] desktop;
~*[Ll]inux desktop;
~*[Ff]irefox desktop;
~*[Cc]hrome desktop;
~*[Ss]afari desktop;
}
为不同设备类型定义独立限流区域
每个 limit_req_zone 使用 $device_type 作为键,配合不同内存大小与速率策略:
-
mobile_zone:适配弱网络,允许更高并发但更低单 IP 频率(如10r/s) -
desktop_zone:面向稳定连接,支持更高吞吐(如30r/s) -
other_zone:严格限制未知/异常流量(如2r/s或启用突发+延时拒绝)
示例配置:
limit_req_zone $device_type zone=mobile_zone:10m rate=10r/s; limit_req_zone $device_type zone=desktop_zone:10m rate=30r/s; limit_req_zone $device_type zone=other_zone:10m rate=2r/s;
在 proxy location 中按设备类型选择限流策略
使用 if + set 或直接嵌套 limit_req 指令,根据 $device_type 应用对应 zone:
- 推荐方式:用
if判断后设置限流 zone 名变量,再统一调用limit_req - 注意:
if在 location 块中是安全的,但不能用于 server 级上下文 - 可搭配
burst和nodelay控制突发处理逻辑(如移动端允许短时 burst,爬虫类直接拒绝)
示例配置:
location /api/ {
set $req_zone "";
if ($device_type = mobile) { set $req_zone "mobile_zone"; }
if ($device_type = desktop) { set $req_zone "desktop_zone"; }
if ($device_type = other) { set $req_zone "other_zone"; }
limit_req zone=$req_zone burst=5 nodelay;
proxy_pass http://backend;
proxy_set_header Host $host;
}
增强识别精度与运维可观测性
基础 UA 匹配可能被伪造或覆盖不全,建议补充以下措施:
- 添加
$http_x_requested_with(常用于 AJAX 请求识别)辅助判断是否为前端 SPA 调用 - 通过
log_format记录$device_type,便于分析真实设备分布和限流触发情况 - 对高频
other流量做 UA 日志采样,定期更新map规则 - 配合
limit_req_status 429统一返回状态码,前端/监控系统可据此区分限流原因










