nginx 无法直接基于 cpu/内存等资源占用率限流,但可通过映射高开销请求特征、多维度限流(limit_req + limit_conn)、业务变量键、外部监控联动等方式间接实现资源级防护。

直接用 Nginx 做“基于资源占用率”的限流——它本身不支持 CPU、内存等系统指标的实时采集和动态响应。Nginx 的限流机制是请求维度的,不是资源维度的。但它能通过合理设计,间接实现对资源压力的有效管控,关键在于把“资源占用风险”映射到可识别、可计量的请求特征上。
识别高资源消耗行为并针对性限流
真正压垮服务器的往往不是总请求数,而是特定类型请求。比如:大文件下载、未加索引的搜索接口、图片实时缩放、复杂报表导出。这些操作单次耗时长、CPU/内存开销大,但并发数可能不高。
- 为高开销路径单独配置 location,例如
/report/export、/api/analyze - 使用
limit_req_zone按$server_name或$request_uri定义区域,而非只按 IP —— 防止某租户一个接口拖垮整台机器 - 设置极低速率(如
rate=2r/m)+ 小 burst(如burst=3),避免排队堆积
结合连接数与请求速率双重控制
单一限流容易被绕过。比如用长连接维持大量空闲连接,或用低频高频小请求持续占满线程池。必须叠加限制:
- 用
limit_conn_zone $binary_remote_addr zone=perip:10m;控制每个客户端最大并发连接数(如limit_conn perip 5;) - 在关键 location 中同时启用
limit_req和limit_conn,两者独立生效 - 对上传、下载类 location,额外加
client_max_body_size和client_body_timeout,防大包慢传耗尽连接
利用变量构造业务感知型限流键
让限流规则理解业务逻辑,而不是机械地按 IP 或 URL 切割:
- 提取请求头中的租户标识:
limit_req_zone $http_x_tenant_id zone=tenant:10m rate=10r/s; - 区分用户角色:
map $http_authorization $user_role { ~Bearer.*admin admin; default user; },再按$user_role分区限流 - 对登录、密码重置等敏感操作,用
$http_user_agent+$binary_remote_addr组合键,防账号爆破
配合外部信号做软性干预
当真实资源指标超标时,Nginx 虽不能自动调整限流阈值,但可以响应外部通知:
- 用
stub_status模块暴露活跃连接数、处理请求数,供监控系统采集 - 当 CPU > 85% 或连接数 > 90% 时,运维脚本修改 Nginx 配置中对应 zone 的
rate值(如从50r/s降至10r/s),然后nginx -s reload - 更平滑的做法:用 OpenResty 或 Lua 模块读取 Prometheus 数据,动态设置
limit_req的参数(需编译支持)
本质上,Nginx 的角色是“流量守门员”,不是“资源调度器”。它的价值在于前置拦截、快速响应、低开销执行。把资源保护逻辑拆解成可匹配的请求模式,再辅以外部监控联动,就能构建出稳定、可维护、贴近业务的安全限流防线。











