Nginx提供了多种限流机制来控制客户端请求速率,防止服务器过载。以下是主要的实现方法:
限制同一IP的并发连接数:
http {
limit_conn_zone $binary_remote_addr zone=perip:10m;
limit_conn_status 429;
server {
location / {
limit_conn perip 10; # 每个IP最多10个并发连接
}
}
}
限制请求处理速率:
http {
limit_req_zone $binary_remote_addr zone=perip:10m rate=10r/s;
limit_req_status 429;
server {
location / {
limit_req zone=perip burst=20 nodelay;
# rate=10r/s 基础速率
# burst=20 突发请求缓冲
# nodelay 不延迟处理突发请求
}
}
}
限制客户端下载速度:
location /download/ {
limit_rate 100k; # 限制为100KB/s
limit_rate_after 1m; # 前1MB不限速
}
http {
limit_req_zone $binary_remote_addr zone=perip:10m rate=5r/s;
limit_req_zone $server_name zone=perserver:10m rate=100r/s;
server {
location /api/ {
limit_req zone=perip burst=10 nodelay;
limit_req zone=perserver burst=50;
}
}
}
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;
使用OpenResty实现更灵活的限流:
http {
lua_shared_dict my_limit_req_store 100m;
server {
location / {
access_by_lua_block {
local limit_req = require "resty.limit.req"
local lim, err = limit_req.new("my_limit_req_store", 10, 20)
local delay, err = lim:incoming(ngx.var.binary_remote_addr, true)
if not delay then
if err == "rejected" then
return ngx.exit(503)
end
ngx.log(ngx.ERR, "failed to limit req: ", err)
return ngx.exit(500)
end
}
}
}
}
以上配置可根据实际业务需求进行调整组合,实现最适合的限流策略。