为什么在大门限流
限流的漏斗有三层(呼应限流与熔断系列):Nginx 粗筛(按 IP 挡刷子与脚本)、网关细控(按用户/接口精确配额)、应用兜底(线程池与信号量)。Nginx 的位置决定了它的手段最粗——认不出用户,只认 IP——但成本也最低:垃圾流量根本到不了应用,Java 进程连一个线程都不用花。
limit_req_zone 拆解
http {
# 定义限流规则:按 IP 限,每个 IP 占 10M 记忆空间,速率 10 req/s
limit_req_zone $binary_remote_addr zone=perip:10m rate=10r/s;
# $binary_remote_addr 比 $remote_addr 省 4 倍内存,必用
# 10M 大约能记 16 万个 IP,按业务量算
server {
location /api/ {
limit_req zone=perip burst=20 nodelay;
# burst=20:允许桶里攒 20 个突发额度
# nodelay:突发额度内的请求立即放行,不排队
limit_req_status 429; # 被限流返回 429(默认 503)
}
}
}burst 与 nodelay 的语义
rate=10r/s 不代表"每秒只能来 10 个",它是令牌生成速率。三种组合的行为差别要分清:不加 burst——超速即拒,最狠,正常用户双击都中枪;加 burst 不加 nodelay——超速的请求排队等待,虽然不拒但延迟飙升,前端超时重试反而更糟(呼应重试风暴);burst + nodelay——突发额度内立即处理,额度外的果断拒绝,这是绝大多数场景的正确答案。
limit_conn:另一把尺子
limit_conn_zone $binary_remote_addr zone=connperip:10m;
location /download/ {
limit_conn connperip 5; # 单 IP 同时最多 5 个连接
# 适合治"下载器开 100 个线程狂拉文件"
# 与 limit_req 是两把尺子:一个管速率,一个管并发,常配合用
}白名单与灰度
一刀切限流最容易误伤自己人——监控探针、内网压测机、办公网出口。用 geo 模块给白名单发通行证:
geo $limited {
default 1; # 普通访客:受限
192.168.0.0/16 0; # 内网:不限
203.0.113.7 0; # 监控探针:不限
}
map $limited $limit_key {
0 ""; # 白名单 key 为空 → 不参与限流
1 $binary_remote_addr;
}
limit_req_zone $limit_key zone=perip:10m rate=10r/s;参数怎么定?从压测容量倒推:应用实测单机扛 1000 QPS,按每秒每 IP 峰值请求估算设 rate,宁可先松后紧——限流值是运营资产不是技术洁癖。被限流的 429 也要进监控(呼应日志篇),限流生效的曲线本身就是攻击或异常的信号。下一篇把 HTTPS 一次配齐。
评论 (0)