nginx限流功能的详细配置示例
# 基本概念
limit_req_zone 用来限制单位时间内的请求数,即速率限制,采用的漏桶算法 “leaky bucket”。
limit_req_zone 参数配置
Syntax: limit_req zone=name [burst=number] [nodelay];
Default: —
Context: http, server, location
配置示例
`limit_req_zone $binary_remote_addr zone=one:10m rate=10r/s;`
第一个参数:$binary_remote_addr 表示通过remote_addr这个标识来做限制,"binary_"的目的是缩写内存占用量,是限制同一客户端ip地址。
第二个参数:zone=one:10m表示生成一个大小为10M,名字为one的内存区域,用来存储访问的频次信息。
第三个参数:rate=10r/s表示允许相同标识的客户端的访问频次,这里限制的是每秒10次,还可以有比如30r/m的。
配置示例
`limit_req zone=one burst=30 nodelay;`
第一个参数:zone=one 设置使用哪个配置区域来做限制,与上面limit_req_zone 里的name对应。
第二个参数:burst=30,重点说明一下这个配置,burst爆发的意思,这个配置的意思是设置一个大小为5的缓冲区当有大量请求(爆发)过来时,超过了访问频次限制的请求可以先放到这个缓冲区内。
第三个参数:nodelay,如果设置,超过访问频次而且缓冲区也满了的时候就会直接返回503,如果没有设置,则所有请求会等待排队。
geo 对于白名单(子网或IP都可以) 将返回0,其他IP将返回1。
map 将whiteiplist转换为 limit,如果是 $limit 是0(白名单),则返回空字符串;如果是1,则返回客户端实际IP。
limit_req_zone 限流的key不再使用 binary_remote_addr,而是limit来动态获取值。
如果是白名单,limit_req_zone 的限流key则为空字符串,将不会限流;
若不是白名单,将会对客户端真实IP进行限流。
参考使用模板配置
http {
# 限流白名单
geo $whiteiplist {
default 1;
127.0.0.1 0;
192.168.100.0/24 0;
117.159.26.211 0;
}
map $whiteiplist $limit {
0 "";
1 $binary_remote_addr;
}
# 定义请求限流zone(基于客户端IP)
# $binary_remote_addr:用二进制格式存储客户端IP,节省空间
# zone=req_limit:10m:创建名为req_limit的共享内存区,10MB大小
# rate=10r/s:限制每秒10个请求(也可以用r/m表示分钟)
#limit_req_zone $binary_remote_addr zone=req_limit:10m rate=10r/s;
limit_req_zone $limit zone=req_limit:10m rate=10r/s;
# 定义连接数限制zone
# zone=conn_limit:10m:创建名为conn_limit的共享内存区
#limit_conn_zone $binary_remote_addr zone=conn_limit:10m;
limit_conn_zone $limit zone=conn_limit:10m;
server {
listen 80;
server_name example.com;
# 应用请求限流
# zone=req_limit:使用前面定义的限流zone
# burst=20:允许突发20个请求排队
# nodelay:不延迟处理突发请求(立即扣减burst计数)
limit_req zone=req_limit burst=20 nodelay;
# 应用连接数限制
# 每个IP同时最多保持20个连接
limit_conn conn_limit 20;
# 可选:对特定URI做更严格的限制
location /api/ {
limit_req zone=req_limit burst=5;
limit_conn conn_limit 5;
}
}
}
# 一、基础限流配置
## 1. 连接数限制(ngx_http_limit_conn_module)
http {
定义共享内存区(10MB空间,存储连接状态)
limit_conn_zone $binary_remote_addr zone=conn_limit:10m;
server {
listen 80;
server_name example.com;
# 全局限流(单个IP最大并发连接数)
limit_conn conn_limit 50; # 限制每个IP最多50个并发连接
location / {
proxy_pass http://backend;
}
# 特殊路径单独限流
location /api/sensitive {
limit_conn conn_limit 10; # 敏感接口更严格限制
}
}
}
说明:
`zone=conn_limit:10m:分配10MB内存存储IP请求状态,约支持16万独立IP。`
## 2. 请求速率限制(ngx_http_limit_req_module)
http {
定义速率限制区(10MB空间,存储请求状态)
limit_req_zone $binary_remote_addr zone=api_limit:10m rate=10r/s; # 全局限速10请求/秒
server {
listen 80;
server_name api.example.com;
location /api/ {
# 基础速率限制
limit_req zone=api_limit burst=20 nodelay; # 突发20请求,不延迟处理
# 组合连接数限制
limit_conn conn_limit 20;
proxy_pass http://backend_api;
}
}
}
说明:
`rate=10r/s:限制每个IP每秒最多10个请求。`
`burst=20:允许突发20个请求进入队列,避免误伤正常用户。`
`nodelay:直接处理队列中的请求(无延迟),若需平滑限流可移除该参数。`
# 二、高级限流场景
## 1. 分层限流策略
http {
定义多层限流区
limit_req_zone $binary_remote_addr zone=global_limit:10m rate=100r/s; # 全局限速
limit_req_zone $server_name zone=server_limit:10m rate=50r/s; # 服务器级限速
server {
listen 80;
server_name pay.example.com;
location /payment/ {
# 多层限流叠加
limit_req zone=global_limit burst=50;
limit_req zone=server_limit burst=30;
# 最终生效规则:min(100r/s, 50r/s) = 50r/s,突发队列总长度80
proxy_pass http://payment_backend;
}
}
}
## 2. 动态限流(需Nginx Plus)
http {
基于服务状态的动态限流
limit_req_status 503; # 自定义限流响应码
limit_req_zone $binary_remote_addr zone=dynamic_limit:10m rate=5r/s;
server {
listen 80;
server_name dynamic.example.com;
location / {
# 结合服务健康度动态调整限流阈值
limit_req zone=dynamic_limit
burst=10
nodelay
window=2s; # 滑动窗口时间范围
proxy_pass http://backend_service;
health_check; # 需配合Nginx Plus健康检查
}
}
}
## 3. 地理围栏限流
http {
定义地理限流区(需GeoIP模块)
map $geoip_country_code $allowed_country {
default no;
CN yes;
US yes;
}
limit_req_zone $binary_remote_addr zone=geo_limit:10m rate=5r/s;
server {
listen 80;
server_name global.example.com;
location / {
if ($allowed_country = no) {
limit_req zone=geo_limit burst=2 nodelay; # 非允许国家更严格限流
}
proxy_pass http://global_backend;
}
}
}
# 三、监控与调试配置
## 1. 实时状态监控
http {
server {
listen 8080;
server_name status.example.com;
location /limit_status {
# 自定义限流状态页(需Lua模块)
content_by_lua_block {
local zone = ngx.shared.api_limit
ngx.say("Active requests: ", zone.active)
ngx.say("Rejected requests: ", zone.rejected)
}
allow 192.168.1.0/24;
deny all;
}
}
}
## 2. 详细日志记录
http {
log_format限流日志 '$remote_addr - \(remote_user [\)time_local] '
'"$request" $status \(body_bytes_sent '
'"\)http_referer" "\(http_user_agent" '
'\)limit_rate \(limit_conn ' # 记录限流状态,好像不管用,nginx配置文件检测报错
'\)upstream_response_time';
access_log /var/log/nginx/limit_access.log限流日志;
}
# 四、性能调优建议
内存优化
共享内存区大小计算公式:预估并发用户数 × (记录大小 + 指针大小)
典型记录大小:IPv4约32字节,IPv6约128字节
突发处理
burst参数应设置为平均速率 × 突发时间窗口(例如:100r/s × 5s = 500)
结合nodelay参数实现立即处理突发请求
滑动窗口优化
使用window参数替代默认漏桶算法(需Nginx 1.19+)
示例:limit_req zone=name rate=10r/s window=2s; 实现2秒内10请求的平滑限制
# 五、安全加固方案
## 1. 组合防护配置
http {
定义多层防护区
limit_conn_zone $binary_remote_addr zone=conn_zone:10m;
limit_req_zone $binary_remote_addr zone=req_zone:10m rate=20r/s;
server {
listen 443 ssl;
server_name secure.example.com;
location /api/v1/ {
# 连接数限制
limit_conn conn_zone 30;
# 请求速率限制
limit_req zone=req_zone burst=50 nodelay;
proxy_pass http://secure_backend;
}
}
}
## 2. 自动封禁配置(需Fail2ban)
/etc/fail2ban/jail.local
[DEFAULT]
bantime = 1h # 封禁时间(1 小时)
findtime = 10m # 查找时间窗(10 分钟)
maxretry = 5 # 最大失败次数(超出则封禁)
[nginx-limit-req]
enabled = true
port = http,https
logpath = %(nginx_error_log)s # nginx默认错误日志路径:/var/log/nginx/error.log
[nginx-http-auth]
mode = normal
enabled = true
port = http,https
logpath = %(nginx_error_log)s
[nginx-botsearch]
enabled = true
port = http,https
logpath = %(nginx_error_log)s
[nginx-bad-request]
enabled = true
port = http,https
logpath = %(nginx_access_log)s
[nginx-forbidden]
enabled = true
port = http,https
logpath = %(nginx_error_log)s
## 六、配置验证与测试
- 语法检查
`nginx -t -c /etc/nginx/nginx.conf`
- 压力测试
使用wrk进行限流测试
wrk -t4 -c100 -d30s --latency http://api.example.com/api/
- 实时监控
观察限流计数器
watch -n1 "nginx -s limit_status"
分析访问日志
awk '/limit_conn/ || /limit_req/' /var/log/nginx/access.log
# 七、最佳实践建议
分级限流策略
基础层:全局限速(防止DDoS)
业务层:接口级限速(保护核心服务)
用户层:单个用户限速(防止刷接口)
动态调整机制
结合Prometheus监控指标,通过API动态修改限流阈值
示例:使用ngx_http_lua_module实现动态配置加载
容灾设计
配置limit_req_status 503返回自定义错误页
结合proxy_next_upstream实现服务降级
通过合理配置限流策略,可有效防御DDoS攻击、保护后端服务、维护系统稳定性。实际部署时建议通过全链路压测确定阈值,并结合业务增长情况定期调整限流参数。

浙公网安备 33010602011771号