
在 Nginx 中限制访问频率(请求速率或并发连接数)可以有效防止恶意刷请求、DDoS 攻击或过载后端服务。以下是详细的配置方法和场景示例:
一、限制请求速率(Rate Limiting)
1. 基于 IP 限制每秒请求数
http {
# 定义限流规则(10MB 内存存储计数,每秒允许 10 请求)
limit_req_zone $binary_remote_addr zone=req_limit:10m rate=10r/s;
server {
listen 80;
server_name example.com;
# 应用限流规则(突发请求不超过 20)
location /api/ {
limit_req zone=req_limit burst=20 nodelay;
proxy_pass http://backend;
}
}
}
- 参数说明:
limit_req_zone
:定义共享内存区(zone
)和速率(rate
)。$binary_remote_addr
:以客户端 IP 作为限流键。zone=req_limit:10m
:分配 10MB 内存存储计数状态(约可记录 16 万 IP)。rate=10r/s
:每秒允许 10 请求(或使用60r/m
表示每分钟 60 次)。
limit_req
:应用限流规则。burst=20
:允许突发 20 请求(超出速率的请求排队等待)。nodelay
:立即处理突发请求,但不突破总体速率限制(若无此参数,突发请求会被延迟处理)。
2. 按 URL 路径差异化限流
limit_req_zone $binary_remote_addr zone=api_limit:10m rate=5r/s;
limit_req_zone $binary_remote_addr zone=static_limit:10m rate=20r/s;
location /api/ {
limit_req zone=api_limit burst=10;
proxy_pass http://backend;
}
location /static/ {
limit_req zone=static_limit burst=30;
root /var/www;
}
二、限制并发连接数(Connection Limiting)
1. 限制单个 IP 的并发连接数
http {
# 定义并发连接限制区(10MB 内存,键为客户端 IP)
limit_conn_zone $binary_remote_addr zone=conn_limit:10m;
server {
listen 80;
server_name example.com;
# 每个 IP 最多 5 个并发连接
location /download/ {
limit_conn conn_limit 5;
limit_rate 100k; # 限速 100KB/s(可选)
root /var/www;
}
}
}
- 关键指令:
limit_conn_zone
:定义共享内存区。limit_conn
:设置每个键(如 IP)的最大并发连接数。limit_rate
:限制单个连接的下载速度(可选)。
2. 限制整个服务的总并发连接数
events {
worker_connections 1024; # 单个 Worker 的最大连接数
}
http {
server {
listen 80;
server_name example.com;
# 全局限制(需结合 worker_processes 计算)
}
}
- 总并发 =
worker_processes
×worker_connections
。
三、高级场景配置
1. 白名单排除(不限制内网 IP)
geo $limit {
default 1;
192.168.1.0/24 0; # 内网 IP 不限速
}
map $limit $limit_key {
0 "";
1 $binary_remote_addr;
}
limit_req_zone $limit_key zone=req_limit:10m rate=10r/s;
location / {
limit_req zone=req_limit burst=20;
proxy_pass http://backend;
}
2. 结合 User-Agent 限制爬虫
map $http_user_agent $is_bot {
default 0;
"~*(Googlebot|Bingbot)" 1;
}
limit_req_zone $binary_remote_addr zone=bot_limit:10m rate=2r/s;
location / {
limit_req zone=bot_limit burst=5 if=$is_bot;
proxy_pass http://backend;
}
四、验证与调试
1. 测试限流效果
# 模拟高并发请求(10 线程,共 100 请求)
ab -n 100 -c 10 http://example.com/api/
# 查看被拒绝的请求(日志路径见 error_log)
tail -f /var/log/nginx/error.log
- 触发限流时,日志会记录
503 (Service Temporarily Unavailable)
错误。
2. 监控限流状态
location /status {
stub_status on;
allow 127.0.0.1;
deny all;
}
- 访问
http://localhost/status
查看当前连接数和请求状态。
五、注意事项
内存分配
limit_req_zone
的10m
可存储约 16 万 IP 状态,根据业务规模调整。
突发流量处理
burst
参数允许短暂超限,但需权衡服务承受能力。
日志记录
- 被限流的请求默认记录到
error_log
,建议单独监控:limit_req_status 429; # 自定义返回状态码(默认 503) access_log /var/log/nginx/rate_limited.log combined;
- 被限流的请求默认记录到
分布式限流
- 若 Nginx 前置有负载均衡,需改用
$http_x_forwarded_for
替代$binary_remote_addr
。
- 若 Nginx 前置有负载均衡,需改用
完整配置示例
http {
# 定义限流规则
limit_req_zone $binary_remote_addr zone=api_limit:10m rate=10r/s;
limit_conn_zone $binary_remote_addr zone=conn_limit:10m;
server {
listen 80;
server_name example.com;
# API 限流:每秒 10 请求,突发 20
location /api/ {
limit_req zone=api_limit burst=20 nodelay;
limit_conn conn_limit 5; # 每个 IP 最多 5 并发
proxy_pass http://backend;
}
# 静态文件限速下载
location /download/ {
limit_conn conn_limit 3; # 每个 IP 最多 3 并发
limit_rate 500k; # 限速 500KB/秒
root /var/www;
}
}
}
通过以上配置,可有效防护恶意请求,同时保障正常用户的访问体验。
学在每日,进无止境!更多精彩内容请关注微信公众号。

原文出处:
内容由AI生成仅供参考,请勿使用于商业用途。如若转载请注明原文及出处。
出处地址:http://www.07sucai.com/tech/965.html
版权声明:本文来源地址若非本站均为转载,若侵害到您的权利,请及时联系我们,我们会在第一时间进行处理。