Nginx限流限速 #
一、限流概述 #
1.1 为什么需要限流 #
- 防止DDoS攻击
- 保护后端服务
- 公平分配资源
- 控制带宽使用
1.2 Nginx限流方式 #
| 方式 | 说明 | 模块 |
|---|---|---|
| 请求频率限制 | 限制请求速率 | ngx_http_limit_req_module |
| 连接数限制 | 限制并发连接数 | ngx_http_limit_conn_module |
| 带宽限制 | 限制传输速率 | ngx_http_core_module |
二、请求频率限制 #
2.1 基本配置 #
nginx
http {
limit_req_zone $binary_remote_addr zone=req_limit:10m rate=10r/s;
server {
location /api/ {
limit_req zone=req_limit;
proxy_pass http://backend;
}
}
}
2.2 参数说明 #
nginx
limit_req_zone key zone=name:size rate=rate;
| 参数 | 说明 |
|---|---|
| key | 限流键(如IP) |
| zone | 共享内存区域名称和大小 |
| rate | 请求速率(如10r/s表示每秒10个请求) |
2.3 burst突发请求 #
nginx
location /api/ {
limit_req zone=req_limit burst=20;
proxy_pass http://backend;
}
burst允许突发请求数,超过rate的请求会排队等待。
2.4 nodelay立即处理 #
nginx
location /api/ {
limit_req zone=req_limit burst=20 nodelay;
proxy_pass http://backend;
}
nodelay让突发请求立即处理,不排队等待。
2.5 返回自定义状态码 #
nginx
limit_req_status 429;
2.6 不同路径不同限制 #
nginx
http {
limit_req_zone $binary_remote_addr zone=api_limit:10m rate=10r/s;
limit_req_zone $binary_remote_addr zone=login_limit:10m rate=1r/s;
server {
location /api/ {
limit_req zone=api_limit burst=20 nodelay;
proxy_pass http://backend;
}
location /login {
limit_req zone=login_limit burst=5;
proxy_pass http://backend;
}
}
}
2.7 白名单配置 #
nginx
http {
geo $limit_key {
default $binary_remote_addr;
127.0.0.1 "";
192.168.0.0/16 "";
}
limit_req_zone $limit_key zone=req_limit:10m rate=10r/s;
server {
location /api/ {
limit_req zone=req_limit burst=20;
proxy_pass http://backend;
}
}
}
三、连接数限制 #
3.1 基本配置 #
nginx
http {
limit_conn_zone $binary_remote_addr zone=conn_limit:10m;
server {
location / {
limit_conn conn_limit 10;
proxy_pass http://backend;
}
}
}
3.2 参数说明 #
nginx
limit_conn_zone key zone=name:size;
limit_conn zone number;
3.3 返回自定义状态码 #
nginx
limit_conn_status 429;
3.4 限制总连接数 #
nginx
http {
limit_conn_zone $server_name zone=server_conn:10m;
server {
limit_conn server_conn 1000;
}
}
3.5 组合限制 #
nginx
http {
limit_req_zone $binary_remote_addr zone=req_limit:10m rate=10r/s;
limit_conn_zone $binary_remote_addr zone=conn_limit:10m;
server {
location /api/ {
limit_req zone=req_limit burst=20 nodelay;
limit_conn conn_limit 10;
proxy_pass http://backend;
}
}
}
四、带宽限制 #
4.1 limit_rate指令 #
nginx
location /download/ {
limit_rate 1m;
alias /var/www/download/;
}
4.2 动态限速 #
nginx
location /download/ {
set $limit_rate 1m;
alias /var/www/download/;
}
4.3 初始不限速 #
nginx
location /download/ {
limit_rate 1m;
limit_rate_after 10m;
alias /var/www/download/;
}
前10MB不限速,之后限速1MB/s。
4.4 按用户限速 #
nginx
map $cookie_user_type $rate_limit {
default 1m;
premium 10m;
vip 100m;
}
server {
location /download/ {
limit_rate $rate_limit;
alias /var/www/download/;
}
}
五、漏桶算法 #
5.1 算法原理 #
text
请求 → [漏桶] → 处理
↓
溢出丢弃
- 桶以固定速率漏水(处理请求)
- 请求以任意速率进入桶中
- 桶满时溢出(拒绝请求)
5.2 Nginx实现 #
nginx
limit_req_zone $binary_remote_addr zone=leaky_bucket:10m rate=10r/s;
location /api/ {
limit_req zone=leaky_bucket burst=20 nodelay;
}
5.3 参数对应 #
| 概念 | Nginx参数 |
|---|---|
| 漏水速率 | rate |
| 桶容量 | burst |
| 立即处理 | nodelay |
六、高级限流 #
6.1 基于请求头限流 #
nginx
map $http_x_api_key $limit_key {
default $binary_remote_addr;
"" $binary_remote_addr;
"premium_key" "";
}
limit_req_zone $limit_key zone=api_limit:10m rate=10r/s;
6.2 基于URI限流 #
nginx
map $uri $limit_rate {
default 10r/s;
"/api/search" 5r/s;
"/api/download" 1r/s;
}
limit_req_zone $binary_remote_addr zone=uri_limit:10m rate=$limit_rate;
6.3 动态限流 #
nginx
map $time_iso8601 $rate_multiplier {
default 1;
"~T(09|10|11|14|15|16|17):" 0.5;
}
limit_req_zone $binary_remote_addr zone=dynamic_limit:10m rate=${10r/s*$rate_multiplier};
6.4 分布式限流 #
使用Redis实现分布式限流:
nginx
location /api/ {
access_by_lua_block {
local redis = require "resty.redis"
local red = redis:new()
local res, err = red:incr("rate_limit:" .. ngx.var.remote_addr)
if res == 1 then
red:expire("rate_limit:" .. ngx.var.remote_addr, 1)
end
if res and res > 10 then
ngx.exit(429)
end
}
proxy_pass http://backend;
}
七、限流日志 #
7.1 记录限流日志 #
nginx
limit_req_log_level warn;
limit_conn_log_level warn;
7.2 自定义日志格式 #
nginx
log_format limit '$remote_addr - [$time_local] "$request" '
'$status $body_bytes_sent '
'limit_req_status=$limit_req_status '
'limit_conn_status=$limit_conn_status';
八、DDoS防护 #
8.1 基础防护 #
nginx
http {
limit_req_zone $binary_remote_addr zone=ddos_limit:10m rate=10r/s;
limit_conn_zone $binary_remote_addr zone=ddos_conn:10m;
server {
limit_req zone=ddos_limit burst=50 nodelay;
limit_conn ddos_conn 20;
limit_req_status 429;
limit_conn_status 429;
}
}
8.2 连接超时防护 #
nginx
server {
client_body_timeout 5s;
client_header_timeout 5s;
keepalive_timeout 10s;
send_timeout 5s;
}
8.3 请求体大小限制 #
nginx
server {
client_max_body_size 1m;
client_body_buffer_size 128k;
}
8.4 Slowloris防护 #
nginx
server {
client_body_timeout 5s;
client_header_timeout 5s;
limit_conn_zone $binary_remote_addr zone=slow_conn:10m;
limit_conn slow_conn 10;
}
九、限流策略 #
9.1 API限流 #
nginx
http {
limit_req_zone $binary_remote_addr zone=api_limit:10m rate=100r/s;
server {
location /api/ {
limit_req zone=api_limit burst=200 nodelay;
limit_req_status 429;
proxy_pass http://backend;
}
}
}
9.2 登录限流 #
nginx
http {
limit_req_zone $binary_remote_addr zone=login_limit:10m rate=1r/s;
server {
location /login {
limit_req zone=login_limit burst=5 nodelay;
limit_req_status 429;
proxy_pass http://backend;
}
}
}
9.3 下载限流 #
nginx
server {
location /download/ {
limit_rate 1m;
limit_rate_after 10m;
alias /var/www/download/;
}
}
9.4 搜索限流 #
nginx
http {
limit_req_zone $binary_remote_addr zone=search_limit:10m rate=5r/s;
server {
location /search {
limit_req zone=search_limit burst=10;
proxy_pass http://backend;
}
}
}
十、监控与调试 #
10.1 查看限流状态 #
nginx
location /nginx_status {
stub_status on;
access_log off;
allow 127.0.0.1;
deny all;
}
10.2 日志分析 #
bash
grep "429" /var/log/nginx/access.log | wc -l
awk '$9 == 429 {print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head -10
十一、完整配置示例 #
nginx
http {
limit_req_zone $binary_remote_addr zone=api_limit:10m rate=100r/s;
limit_req_zone $binary_remote_addr zone=login_limit:10m rate=1r/s;
limit_req_zone $binary_remote_addr zone=search_limit:10m rate=5r/s;
limit_conn_zone $binary_remote_addr zone=conn_limit:10m;
geo $limit_key {
default $binary_remote_addr;
127.0.0.1 "";
192.168.0.0/16 "";
10.0.0.0/8 "";
}
limit_req_zone $limit_key zone=whitelist_limit:10m rate=1000r/s;
server {
listen 80;
server_name api.example.com;
client_body_timeout 5s;
client_header_timeout 5s;
client_max_body_size 10m;
limit_req_status 429;
limit_conn_status 429;
limit_req_log_level warn;
location / {
limit_conn conn_limit 20;
limit_req zone=whitelist_limit burst=100 nodelay;
proxy_pass http://backend;
}
location /api/ {
limit_conn conn_limit 20;
limit_req zone=api_limit burst=200 nodelay;
proxy_pass http://backend;
}
location /login {
limit_conn conn_limit 5;
limit_req zone=login_limit burst=5 nodelay;
proxy_pass http://backend;
}
location /search {
limit_conn conn_limit 10;
limit_req zone=search_limit burst=10;
proxy_pass http://backend;
}
location /download/ {
limit_rate 1m;
limit_rate_after 10m;
limit_conn conn_limit 3;
alias /var/www/download/;
}
location /nginx_status {
stub_status on;
access_log off;
allow 127.0.0.1;
deny all;
}
}
}
十二、总结 #
本章我们学习了:
- 请求频率限制:limit_req_zone和limit_req
- 连接数限制:limit_conn_zone和limit_conn
- 带宽限制:limit_rate和limit_rate_after
- 漏桶算法:原理和Nginx实现
- 高级限流:基于请求头、URI、动态限流
- DDoS防护:基础防护和Slowloris防护
- 限流策略:API、登录、下载、搜索
- 监控调试:状态监控和日志分析
掌握限流限速后,让我们进入下一章,学习性能优化!
最后更新:2026-03-27