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;
        }
    }
}

十二、总结 #

本章我们学习了:

  1. 请求频率限制:limit_req_zone和limit_req
  2. 连接数限制:limit_conn_zone和limit_conn
  3. 带宽限制:limit_rate和limit_rate_after
  4. 漏桶算法:原理和Nginx实现
  5. 高级限流:基于请求头、URI、动态限流
  6. DDoS防护:基础防护和Slowloris防护
  7. 限流策略:API、登录、下载、搜索
  8. 监控调试:状态监控和日志分析

掌握限流限速后,让我们进入下一章,学习性能优化!

最后更新:2026-03-27