宝塔面板不支持图形化每秒请求限频,必须手动配置Nginx的limit_req_zone和limit_req指令实现QPS控制,如限制首页10r/s需在http块定义区域并在location /中启用,且需重载配置;按UA或URL限流需配合map指令,旧版Tengine可能不支持if=参数;Shell脚本封IP属事后补救,非实时限流;burst与nodelay组合影响响应行为,线上建议burst=20起步并观察error日志调整。

直接在 Nginx 配置里加 limit_req_zone 和 limit_req
宝塔面板本身不提供图形化“每秒请求次数”的精细控制,所谓“访问限制”功能(在站点设置 → 访问限制)只支持 IP 黑白名单、地域屏蔽、UA 过滤等粗粒度规则,**无法按秒限频**。真要控 QPS,必须手写 Nginx 限流指令。
核心是两步:先定义共享内存区(limit_req_zone),再在具体位置启用(limit_req)。比如限制所有用户对首页的访问不超过 10 次/秒:
-
http块里加:limit_req_zone $binary_remote_addr zone=perip:10m rate=10r/s; - 进站点设置 → 配置文件 → 在
location /块里加:limit_req zone=perip burst=5 nodelay; - 改完必须点「保存」并「重载配置」,不是重启 Nginx(避免服务中断)
按 URL 或 UA 单独限流要用 map + limit_req_zone
想只限制某个接口(如 /api/login)或只限制爬虫(如 Googlebot),不能靠 $binary_remote_addr 简单匹配,得先用 map 提取特征变量。
例如限制 Googlebot 每秒最多 1 次:
- 在
http块顶部加:map $http_user_agent $is_googlebot { default 0; "~*Googlebot" 1; } - 再定义区域:
limit_req_zone $is_googlebot zone=botlimit:10m rate=1r/s; - 在
location /里加:limit_req zone=botlimit burst=3 if=$is_googlebot;
注意:if= 参数是 Nginx 1.13.6+ 才支持的,旧版宝塔自带的 Tengine 可能不识别,会报错 unknown directive "limit_req" 或直接忽略——务必先查 nginx -v 版本。
用计划任务 + Shell 脚本封高频 IP 是补救手段,不是实时限流
有人推荐写 Shell 脚本分析 access.log,每分钟扫一次,把 1 分钟内访问超 200 次的 IP 加进 ipset 黑名单。这确实有用,但本质是「事后拉黑」,不是「实时限流」。
典型问题包括:
- 脚本依赖
tac和awk时间截取,日志格式稍有变化(比如时区、毫秒、字段顺序)就会漏统计 -
date -d "$last_minutes minutes ago"在部分系统上不兼容,可能返回空时间导致全量匹配 - 封禁后不会自动解封,IP 一旦进黑名单,除非手动删或脚本加定时清理逻辑,否则永久失效
- 无法区分正常刷页面和真实攻击——比如一个用户开 10 个标签页同时刷新,也会被误杀
burst 和 nodelay 的实际效果常被高估
burst=5 不代表“允许突发 5 次”,而是允许最多 5 个请求排队等待;nodelay 表示这 5 个不排队,直接放行——但超出 burst 的请求仍会立刻返回 503(或你设的 limit_req_status)。
真正影响体验的是这个组合:
- 没
nodelay:超频请求会被延迟响应,用户感觉卡顿但不报错 - 有
nodelay:超频请求秒回错误,前端容易炸(尤其 AJAX 接口没做重试) -
burst太小(如 =1):连 F5 刷新都可能触发限流,用户感知极差
线上建议从 burst=20 nodelay 开始试,观察日志里 limit_req 对应的 error 日志频率,再逐步收紧。










