高频限流需优化内存使用而非堆大内存:用$binary_remote_addr替代$remote_addr省15%~20%内存;按路径分级限流,敏感接口单独配zone,静态资源跳过;burst宜设10~20并配nodelay;优先聚合限流(如国家、网段、用户id)。

直接靠堆大内存撑不住高频限流——limit_req_zone 每个活跃 key(如 IP)固定占约 64 字节,10MB 内存最多存 16 万个状态。在低内存设备上,关键不是“多分点内存”,而是让每字节都服务高价值流量。
选轻量 key,省下一半内存
用 $binary_remote_addr 替代 $remote_addr:IPv4 地址从平均 12+ 字符字符串变成固定 4 字节二进制,哈希更稳、冲突更少、内存节省 15%~20%。若后端有 CDN 或代理,配合 set_real_ip_from + real_ip_header 提前还原真实 IP,再转 binary,避免误把 CDN 节点当攻击源。
按需分配 zone,不搞“一区管全站”
把有限内存切给真正需要限流的路径,而不是全局铺开:
- 对登录页、支付接口等敏感路径,单独配小 zone(如 zone=login:2m rate=3r/m),key 用 $binary_remote_addr$http_user_agent 防 UA 轮换爆破
- 静态资源、健康检查、CDN 回源路径,用 map 映射空 key,完全跳过限流存储
- 全局兜底用极小 zone(如 zone=global:1m rate=50r/s),key 设为 $server_name,防整站被刷垮
控制 burst 和淘汰逻辑,减少无效驻留
burst 不是越大越好——缓冲区占内存,且长期无访问的旧记录会挤占新 IP 空间。建议:
- 对短时突发场景(如秒杀预热),设 burst=10~20 + nodelay,快速响应或拒绝,不排队
- 关闭 accept_mutex(高并发时),配合 multi_accept on,让 epoll 一次处理更多连接,降低事件循环开销
- 观察日志中 $limit 变量和 limit_req_log_level warn 输出,识别频繁触发但未被限流的 IP 段,动态调整 map 白名单
用聚合代替单 IP 记录
千万级 IP 不等于千万个要记的状态。低内存下优先压缩维度:
- 按国家限流:用 $geoip2_country_code 作 key,200 多个国家 + 少量子区域,10MB 足够覆盖
- 按网段粗限:对 $http_x_forwarded_for 取前两段(如 192.168),一个 key 对应数百 IP,适合防御扫描类流量
- 已登录用户用 $http_x_user_id,未登录者回落到 IP 前缀,真实用户数远小于 IP 总量










