## 为什么要限
网站公网可达,就要面对爬虫、采集器、批量下载器,它们不懂客气,开满并发把带宽与连接资源吃光,正常用户反而被挤到超时。与其在业务代码里到处打补丁,不如在入口层用 Nginx 的限流模块统一设闸:访问频率、并发连接数、下载速度三个维度都有现成指令,配置一次全站受益。这是成本最低的自我保护,比事后封 IP 被动得多。
## 请求频率限制
limit_req 模块按键限制请求速率,最常用的键是客户端 IP。先在 http 段定义内存区与速率:
nginx limit_req_zone $binary_remote_addr zone=reqperip:10m rate=10r/s;
再在 server 或 location 里引用并允许突发:
nginx limit_req zone=reqperip burst=20 nodelay;
10m 的内存区大约能记录十几万个地址;rate 定义平均速率;burst 允许的突发队列长度;nodelay 让突发请求立即处理而不是排队,超出部分的请求返回限定状态码。速率取值要看业务:普通页面每秒十个请求足够宽裕,登录、验证码、搜索这类敏感接口单独再压一档,用独立的 zone 与更低的 rate。
## 并发与下载速度
连接数限制用 limit_conn,同样先声明内存区再引用:
nginx
limit_conn_zone $binary_remote_addr zone=connperip:10m;
server {
limit_conn connperip 20;
limit_rate 512k;
}
单个 IP 最多二十个并发连接;limit_rate 限制每个连接的下载速度,大文件下载站用它保证一个用户吃不光带宽。对下载目录还可以用 map 依据请求路径只对特定后缀限速,页面加载不受影响。三层参数配合:频率挡住高频轰炸,并发挡住连接堆积,限速挡住大流量拖带。
## 生效验证与注意
改完 nginx -t 检查,reload 后用压测工具短时打一波超阈值请求,观察返回的限定状态码与正常请求是否不受影响,日志里 limit 字段也会记录命中情况。注意事项:阈值先宽后紧逐步压,一上来太紧容易误伤 NAT 出口共用 IP 的校园网与公司用户;限流命中返回的状态码建议自定义成常见的限流码,让客户端能识别重试;对确认的恶意源,下一步就是防火墙或 fail2ban 长期封禁。顺云云服务器带宽有限时,这套入口闸门是保住正常用户体验的第一道防线。