Nginx 流控搞不好,背锅跑路少不了!

Nginx 流控搞不好,背锅跑路少不了!
最新回答
光棍可耻专门浪费卫生纸。

2026-01-28 23:04:29

Nginx流量限制(rate-limiting)是通过漏桶算法实现的,主要用于限制客户端请求速率,防止服务器过载,同时可抵御暴力破解和DDoS攻击。其核心配置包括limit_req_zone(定义共享内存区域和速率)和limit_req(启用限流),并支持突发请求处理(burst)、无延迟排队(nodelay)及白名单等高级功能。

漏桶算法原理

Nginx采用漏桶算法处理流量限制:

  • 水桶模型:客户端请求视为倒入水桶的水,服务器处理能力视为桶底漏水速率。若倒水速率超过漏水速率,多余请求会被丢弃(返回503状态码)。
  • FIFO队列:未被处理的请求按先进先出原则排队,队列长度由burst参数控制。
基础配置指令
  1. limit_req_zone定义共享内存区域和限流参数,通常在HTTP块中配置:

    limit_req_zone $binary_remote_addr zone=mylimit:10m rate=10r/s;

    参数说明:

    Key:如$binary_remote_addr(客户端IP),用于标识请求来源。

    Zone:共享内存区域名称及大小(如mylimit:10m,可存储约16万个IP状态)。

    Rate:最大请求速率(如10r/s,即每100毫秒1个请求)。

  2. limit_req在特定上下文(如location或server块)启用限流:

    location /login/ { limit_req zone=mylimit; proxy_pass
    http://my_upstream;
    }
突发请求处理

默认情况下,超出速率的请求会被直接拒绝(返回503)。通过burst参数允许突发请求排队:

location /login/ { limit_req zone=mylimit burst=20; proxy_pass
http://my_upstream;
}
  • 效果:允许最多20个请求排队,每100毫秒处理1个请求。若队列已满,新请求仍会被拒绝。
无延迟排队(nodelay)

burst可能导致请求延迟,nodelay可优化体验:

location /login/ { limit_req zone=mylimit burst=20 nodelay; proxy_pass
http://my_upstream;
}
  • 效果:立即处理突发请求,但标记队列位置,后续按速率限制释放位置(如每100毫秒释放1个)。若请求超过burst值,仍返回503。
高级配置示例
  1. 白名单结合geo和map指令,对白名单IP免限流:

    geo $limit { default 1; 10.0.0.0/8 0; 192.168.0.0/24 0;}map $limit $limit_key { 0 ""; 1 $binary_remote_addr;}limit_req_zone $limit_key zone=req_zone:10m rate=5r/s;server { location / { limit_req zone=req_zone burst=10 nodelay; }}

    逻辑:白名单IP的$limit_key为空,不触发限流;其他IP限制为每秒5请求。

  2. 多limit_req指令一个location块可配置多个limit_req,取最严格限制:

    http { limit_req_zone $limit_key zone=req_zone:10m rate=5r/s; limit_req_zone $binary_remote_addr zone=req_zone_wl:10m rate=15r/s; server { location / { limit_req zone=req_zone burst=10 nodelay; limit_req zone=req_zone_wl burst=20 nodelay; } }}

    效果:白名单IP限速15r/s,其他IP限速5r/s。

辅助功能
  1. 日志记录默认记录被限流的请求(error级别),可通过limit_req_log_level调整:

    location /login/ { limit_req zone=mylimit burst=20 nodelay; limit_req_log_level warn;}
  2. 自定义错误码使用limit_req_status修改返回状态码:

    location /login/ { limit_req zone=mylimit burst=20 nodelay; limit_req_status 444;}
  3. 拒绝所有请求对特定URL直接拒绝:

    location /foo.php { deny all;}
总结

Nginx流量限制通过漏桶算法实现,核心配置为limit_req_zone和limit_req,支持突发处理(burst)、无延迟排队(nodelay)及白名单等高级功能。合理配置可保护服务器免受过载攻击,同时优化用户体验。建议结合日志记录和错误码自定义,进一步增强运维能力。