Nginx提供了多种限流机制来保护服务器免受过多请求的冲击。以下是几种主要的限流方法及其实现方式:
http {
limit_conn_zone $binary_remote_addr zone=addr:10m;
server {
location / {
limit_conn addr 10; # 每个IP最多10个并发连接
}
}
}
http {
limit_req_zone $binary_remote_addr zone=one:10m rate=10r/s;
server {
location / {
limit_req zone=one burst=20 nodelay;
# rate=10r/s 表示每秒10个请求
# burst=20 表示允许突发20个请求
# nodelay 表示不延迟处理突发请求
}
}
}
location /download/ {
limit_rate 100k; # 限制下载速度为100KB/s
limit_rate_after 1m; # 前1MB不限速
}
http {
limit_req_zone $binary_remote_addr zone=api:10m rate=5r/s;
limit_req_zone $binary_remote_addr zone=static:10m rate=100r/s;
server {
location /api/ {
limit_req zone=api burst=10;
}
location /static/ {
limit_req zone=static 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;
location / {
access_by_lua_block {
local limit_req = require "resty.limit.req"
local lim, err = limit_req.new("my_limit_req_store", 10, 20)
if not lim then
ngx.log(ngx.ERR, "failed to instantiate a resty.limit.req object: ", err)
return ngx.exit(500)
end
local key = ngx.var.binary_remote_addr
local delay, err = lim:incoming(key, 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
if delay >= 0.001 then
ngx.sleep(delay)
end
}
}
limit_req_status 429; # 默认是503,可以改为429(Too Many Requests)
error_page 429 /429.html;
location = /429.html {
internal;
root /usr/share/nginx/html;
}
通过以上方法,可以有效防止服务器因突发流量而过载,同时保证正常用户的访问体验。