灯下哥谭 灯下哥谭
首页
关于
  • Hermes Agent 平台
  • Claude Code
  • OpenClaw
  • GPU 推理节点运维
  • DeepSeek Harness
  • MySQL 运维知识地图
  • Elasticsearch 运维知识地图
  • Redis 运维知识地图
  • TiDB 体系
  • DBA 常用 SQL 与命令
  • Nginx 运维知识地图
  • Prometheus 监控
  • Docker
  • Systemd
  • Iptables
  • Firewalld
  • Sshd
  • MySQL8 运维 SOP 手册
  • MySQL 实战 45 讲(读书笔记)
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

灯下哥谭

灯还亮着
首页
关于
  • Hermes Agent 平台
  • Claude Code
  • OpenClaw
  • GPU 推理节点运维
  • DeepSeek Harness
  • MySQL 运维知识地图
  • Elasticsearch 运维知识地图
  • Redis 运维知识地图
  • TiDB 体系
  • DBA 常用 SQL 与命令
  • Nginx 运维知识地图
  • Prometheus 监控
  • Docker
  • Systemd
  • Iptables
  • Firewalld
  • Sshd
  • MySQL8 运维 SOP 手册
  • MySQL 实战 45 讲(读书笔记)
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • 工作笔记

  • 容器与编排

  • Nginx

    • Nginx 运维知识地图:从配置基础到反向代理实战
    • Nginx 给内部服务加认证:Basic Auth / LDAP / OIDC 三档怎么选
    • 利用nginx+sftp实现一个可供用户下载的服务
    • nginx配置文件及模块
    • Nginx 端口转发与复用:四层代理与 SO_REUSEPORT 实战
    • OpenResty 版本升级与模块管理:从 1.13 到 1.19 的实践
    • NGINX基于cookie针对同一域名进行分流转发
    • nginx利用内置模块配置限速限流
      • 13. 限速与 Gzip 的交互
      • 14. 多维度限速
      • 15. 突发流量处理
      • 16. 监控指标
      • 17. 总结
      • 18. 分布式限速
      • 19. 限速策略调优
      • 20. 常见配置错误
      • 21. 与 CDN 配合
      • 22. 最佳实践检查清单
      • 23. 成本考量
      • 24. 故障恢复
      • 25. 参考资料
      • 26. 相关工具对比
    • 利用NGINX内置模块mirror进行流量复制等操作
    • Nginx 常用配置速查
    • Nginx 日志切割两种方案对比:外部脚本 vs 配置文件原生切割
    • nginx配置微信小程序校验及其他
    • 由Nginx集中代理分散的PHP集群的实践
    • http状态码详解
    • 排查NGINX的open_file_cache导致发布后访问404的问题
    • Nginx Proxy Manager 使用笔记
  • 监控

  • 网络安全

  • 其他

  • Linux笔记
  • Nginx
灯下哥谭
2019-08-18
目录

nginx利用内置模块配置限速限流

有时候 NGINX 面对一些特殊的场景时,需要进行一定的限速限流的配置,比如一个官网,可能前端静态文件是非常小的,但是同时配置的还有一些 apk 包,这些包如果不做任何限制,可能会形成比较大的负载或者带宽的压力。

# 1. 限速限流的典型应用场景

场景一:下载站带宽控制

文件下载类网站需要控制单个下载线程的速度,避免少数大文件下载占用全部带宽,影响其他用户的访问体验。

场景二:API 接口防刷

对外提供的 API 接口需要限制请求频率,防止恶意刷接口或意外的大量并发请求导致服务不可用。

场景三:防止爬虫过度抓取

限制爬虫的访问频率,既保护服务器资源,又避免对后端服务造成过大压力。

# 2. 限速限流的原理

Nginx 的限速限流主要通过两个模块实现:

  • ngx_http_limit_conn_module:限制连接数
  • ngx_http_limit_req_module:限制请求频率

两者的工作机制不同:

  • 连接数限制:基于并发连接数,限制同一 IP 同时建立的连接数量
  • 请求频率限制:基于请求速率,限制每秒/分钟处理的请求数量

# 3. 配置详解

版本说明

本文写于 2019-08,基于 Nginx 1.15。
未在更高版本上重新验证,请以对应版本的官方文档为准。

没有限制之前,对应的包下载速度如下:

img

添加如下配置,进行一定的限制:

http {
    ...#省略
    limit_conn_zone $binary_remote_addr zone=addr:10m;
    ...#省略
}
server {
    listen 80 default;
    server_name localhost;
    location ~ "^/test/app/" {
         limit_conn addr 6;
        limit_rate_after 10m;
        limit_rate 1200k;
        limit_conn_status 499;
        limit_conn_log_level warn;
        root  /app;
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

说明:

  • http 区域使用的是 1.15 版本,默认已安装 ngx_http_limit_conn_module。
    • limit_conn_zone:固定名称,下边调用时对应。
    • $binary_remote_addr:通过 remote_addr 标识做限制,"binary_" 前缀缩写内存占用量,限制同一客户端 IP 地址。
    • zone=addr:10m:生成大小为 10M、名字为 addr 的内存区域,用来存储访问频次信息。
  • server 区域可写在 server 内表示限制所有,也可写到 location 中表示单独区域限制。
    • limit_conn:单个 IP 限制最大连接数为 6。
    • limit_rate_after:请求前 10M 大小时不限速。
    • limit_rate:单个连接最大带宽限制为 1200K。
    • limit_conn_status:设置拒绝请求的返回值(400-599 之间,默认 503)。
    • limit_conn_log_level:定义日志级别,默认 error。

# 4. 验证效果

现在测试一下下载速度:

可以看到速度已经受限,而且是在 10M 之后速度开始慢慢下降,直至达到限制位置。

压测验证:

ab -n 10 -c 10 http://www.test.com/res/app/app-xiaomi-release.apk
1

此命令表示请求 10 次资源,并发为 10。查看日志,因为定义的最大并发是 6,所以会有 4 个失败(返回 499),6 个成功:

$tailf -n 100 a |awk -F "," '{print  $6}'
"response": "499"
"response": "499"
"response": "499"
"response": "499"
"response": "200"
"response": "200"
"response": "200"
"response": "200"
"response": "200"
"response": "200"
1
2
3
4
5
6
7
8
9
10
11

压测输出中,Transfer rate 约为 7M/s,正好是单条限制 1.2M/s 乘以 6 的数值。

# 5. 坑与边界

常见问题一:限速不生效

检查是否在正确的层级配置,limit_conn_zone 必须在 http 层,limit_conn 必须在 server 或 location 层。

常见问题二:内存占用过高

如果连接数很大,需要适当增大 zone 大小。使用 $binary_remote_addr 而非 $remote_addr 可以显著减少内存占用。

常见问题三:与其他模块冲突

与 proxy_cache 等模块配合使用时,注意缓存命中后的行为可能影响限速效果。

# 6. 进阶:请求频率限制

除了连接数限制,还可以用 limit_req 限制请求频率:

http {
    limit_req_zone $binary_remote_addr zone=req_limit:10m rate=10r/s;
}

server {
    location /api/ {
        limit_req zone=req_limit burst=20 nodelay;
    }
}
1
2
3
4
5
6
7
8
9
  • rate=10r/s:每秒 10 个请求
  • burst=20:允许突发 20 个请求
  • nodelay:不等待,立即处理突发请求

# 7. 参考

  • Nginx 限速模块官方文档 (opens new window)
  • Nginx 请求频率限制文档 (opens new window)

# 8. 更多高级配置示例

示例一:基于用户身份的限速

如果需要根据登录用户而不是 IP 来限速,可以使用会话 cookie 或 JWT token:

http {
    limit_req_zone $cookie_session_id zone=session_limit:10m rate=5r/s;
}

server {
    location /api/ {
        limit_req zone=session_limit burst=10 nodelay;
    }
}
1
2
3
4
5
6
7
8
9

示例二:不同路径不同限速策略

server {
    # 下载路径:限制带宽
    location /download/ {
        limit_rate 1024k;  # 单连接 1MB/s
    }
    
    # API 路径:限制请求频率
    location /api/ {
        limit_req zone=api_limit:10m rate=100r/s;
    }
    
    # 上传路径:限制连接数
    location /upload/ {
        limit_conn upload_limit 3;
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

示例三:区域白名单

有时需要对某些 IP 段不做限速(比如内部服务):

geo $limited {
    default 1;
    <内部IP段> 0;
    <内部IP段> 0;
    <内部IP段> 0;
}

map $limited $limit {
    1 $binary_remote_addr;
    0 "";
}

http {
    limit_conn_zone $limit zone=addr:10m;
}

### 9. 参考

- [Nginx 限速模块官方文档](http://nginx.org/en/docs/http/ngx_http_limit_conn_module.html)
- [Nginx 请求频率限制文档](http://nginx.org/en/docs/http/ngx_http_limit_req_module.html)

## 12. 限速与缓存的交互

当 Nginx 同时使用限速和缓存时,需要注意缓存命中后的行为:

**场景**:启用了 proxy_cache,同时配置了 limit_req

```nginx
http {
    limit_req_zone $binary_remote_addr zone=api_limit:10m rate=10r/s;
    
    proxy_cache my_cache;
    proxy_cache_valid 200 10m;
}

server {
    location /api/ {
        limit_req zone=api_limit burst=20 nodelay;
        proxy_cache my_cache;
        proxy_pass http://backend;
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42

注意:缓存命中时,limit_req 仍然生效。因为请求仍然会到达 Nginx,只是直接从缓存返回响应。

# 13. 限速与 Gzip 的交互

启用 gzip 压缩后,传输数据量减少,但压缩计算会消耗 CPU:

http {
    limit_req_zone $binary_remote_addr zone=no_compress:10m rate=5r/s;
}

server {
    location /large-files/ {
        # 大文件下载限速
        limit_rate 1024k;
        limit_rate_after 50m;
        
        # 不启用压缩(压缩大文件不划算)
        gzip off;
    }
    
    location /api/ {
        # API 限速,但不压缩(通常后端已经压缩)
        limit_req zone=api_limit burst=10;
        gzip off;
    }
    
    location /static/ {
        # 静态资源:启用压缩,但不限速(CDN 负责)
        gzip on;
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

# 14. 多维度限速

有时需要同时基于多个维度限速:

方案:IP + 用户ID 组合

http {
    # 基于 IP
    limit_conn_zone $binary_remote_addr zone=ip_limit:10m;
    
    # 基于用户(如果已登录)
    limit_req_zone $cookie_user_id zone=user_limit:10m rate=1r/s;
}

server {
    location /api/ {
        # 同时限制
        limit_conn addr 10;
        limit_req zone=user_limit burst=5;
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

生效逻辑:两个限制会叠加生效,实际限制是两者中更严格的那个。

# 15. 突发流量处理

限速配置中,burst 和 nodelay 参数决定了如何处理突发流量:

配置 行为
无 burst 严格按 rate 限速
burst=N 允许最多 N 个请求排队等待
burst=N nodelay 允许最多 N 个请求立即执行,不等待

使用场景:

# 允许小规模突发
limit_req zone=api_limit burst=10;

# 允许大规模突发(用于营销活动等可预估的峰值)
limit_req zone=api_limit burst=100 nodelay;
1
2
3
4
5

风险提示:nodelay 可能导致后端瞬时压力过大,请根据后端容量合理设置。


# 16. 监控指标

部署限速后,建议监控以下指标:

  1. limit_req 拒绝数:nginxlimitrejected
  2. limit_conn 连接数:nginxlimitconnections
  3. zone 使用率:确保 zone 未满
  4. 响应时间:限速不应显著增加延迟

配置 Prometheus 采集:

location /metrics {
    stub_status on;
    allow 127.0.0.1;
    deny all;
}
1
2
3
4
5

Prometheus 配置抓取 Nginx 状态,然后配合 Grafana 可视化。


# 17. 总结

Nginx 限速模块是保护后端服务的重要手段:

  • 连接数限制(limit_conn):防止并发过高
  • 请求频率限制(limit_req):防止请求过频
  • 带宽限制(limit_rate):防止单连接占用过多带宽

配置要点:

  1. 根据业务流量特征选择合适的限速策略
  2. 合理设置 zone 大小,避免满后误杀
  3. 使用 burst 处理可预期的突发流量
  4. 配合监控及时发现异常

高级技巧:

  • 基于用户身份限速
  • IP 白名单
  • 不同路径不同策略
  • 与缓存、Gzip 等模块配合

# 18. 分布式限速

在集群环境下,单机限速不够精确,需要分布式限速方案:

方案一:Redis 共享状态

lua_shared_dict limit_dict 10m;

server {
    location /api/ {
        access_by_lua_block {
            -- 使用 Redis 计数器实现分布式限速
            local redis = require "resty.redis"
            local red = redis:new()
            red:set_timeout(1000)
            red:connect("127.0.0.1", 6379)
            
            local key = "limit:" .. ngx.var.remote_addr
            local current = red:get(key)
            
            if current and tonumber(current) > 100 then
                ngx.exit(429)
            end
            
            red:incr(key)
            red:expire(key, 1)
        }
        
        proxy_pass http://backend;
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

方案二:一致性哈希

使用 consistent 选项让同一客户端始终路由到同一 upstream:

upstream backend {
   consistent_hash $remote_addr;
    server 192.0.2.11:8080;
    server 192.0.2.12:8080;
}
1
2
3
4
5

# 19. 限速策略调优

根据业务类型选择策略:

业务类型 推荐策略
下载站 limit_rate 限速,限制单连接带宽
API 服务 limit_req 限频率,控制 QPS
登录接口 limit_conn 限并发,防止暴力破解
文件上传 limit_rate + 连接数限制

动态调整:

可以通过接口动态修改限速阈值(需要 Nginx 商业版或 Lua 脚本):

-- 通过管理接口动态调整
ngx.shared.limit_dict:set("rate", 100)  -- 修改为 100r/s
1
2

# 20. 常见配置错误

错误:limit_conn_zone 放在 server 层

# 错误写法
server {
    limit_conn_zone $binary_remote_addr zone=addr:10m;  # 会在 reload 时报错
    ...
}
1
2
3
4
5

正确写法:放在 http 层。

错误:zone 大小设置过小

# 错误:1m 只能存储约 16000 个 KEY
limit_req_zone $binary_remote_addr zone=small:1m rate=10r/s;
1
2

正确:合理预估需要的容量

limit_req_zone $binary_remote_addr zone=addr:10m rate=10r/s;  # 约 160000 个
1

错误:limit_rate 和 limit_req 混用不生效

limit_rate 是单连接带宽限制,limit_req 是请求频率限制,两者针对不同维度,可以同时使用。

# 21. 与 CDN 配合

如果使用 CDN,限速应在边缘节点执行:

# Nginx 只负责回源,不做限速(CDN 负责边缘限速)
upstream origin {
    server 192.0.2.11:8080;
}

server {
    listen 80;
    server_name example.com;
    
    # CDN 回源请求不限速
    if ($http_x_cdn_ip) {
        set $limit_rate 0;
    }
    
    location / {
        proxy_pass http://origin;
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

# 22. 最佳实践检查清单

部署限速前检查:

  • [ ] 确认限速模块已编译进 Nginx:nginx -V | grep limit
  • [ ] zone 大小足够(建议 10m+)
  • [ ] limit_conn 在 http 或 server 层
  • [ ] limit_rate 在 location 层
  • [ ] 测试突发流量场景
  • [ ] 监控 limit 拒绝数
  • [ ] 白名单内部 IP 段
  • [ ] 文档化限速策略

# 23. 成本考量

限速可以节省带宽成本:

场景 节省比例
开启 gzip 约 70%
limit_rate 1Mbps(之前无限制) 约 30-50%
合理配置缓存 约 50%+

# 24. 故障恢复

当限速影响正常业务时:

  1. 临时关闭限速:注释掉 limit 相关配置
  2. 放宽阈值:增大 rate 或 burst 值
  3. 添加白名单:将问题 IP 加入白名单
  4. 回滚配置:使用版本控制回滚到上一版本

监控告警配置建议:

  • 限速拒绝数 > 阈值(如每分钟 100)告警
  • 限速 zone 使用率 > 80% 告警

# 25. 参考资料

  • Nginx limit_conn 模块 (opens new window)
  • Nginx limit_req 模块 (opens new window)
  • Nginx limit_rate 模块 (opens new window)

# 26. 相关工具对比

除了 Nginx 内置模块,还有其他限速工具:

工具 类型 特点
Nginx limit 模块 内置 简单高效,无额外组件
iptables 系统层 能限速整个系统
tc/htb 系统层 更精细的流量控制
云厂商 QoS 云服务 按需付费,配置简单

根据实际需求选择合适的方案。

#安全加固#Nginx
上次更新: 9/11/2026

← NGINX基于cookie针对同一域名进行分流转发 利用NGINX内置模块mirror进行流量复制等操作→

最近更新
01
DeepSeek Harness 实战 06|学习笔记:插件、工具、技能不在同一个维度上 原创
09-11
02
DeepSeek Harness 实战 05|让两个编码 Agent 共用一份长期记忆 原创
09-09
03
DeepSeek Harness 实战 04|学习笔记:从「已知限制」里读出三处设计张力 原创
09-08
更多文章>
Theme by Vdoing
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式