Nginx stream模块仅支持连接数限制(limit_conn),不支持带宽级限速;可通过limit_conn_zone和limit_conn指令限制单IP及总并发连接数,超限直接发送TCP RST;带宽限速需借助tc、HAProxy等外部工具。

Nginx 的 stream 模块(用于 TCP/UDP 代理)不支持带宽级的流量限制,比如上传速率(proxy_upload_rate)或下载速率(proxy_download_rate)。这类指令并不存在于官方 Nginx 中,也不是 stream 上下文的有效配置项。
你真正能做的,只有 连接数限制(limit_conn),它控制的是并发 TCP 连接数量,而非字节传输速度。
✅ TCP 代理中唯一可行的限流方式:连接数限制
这是 stream 模块原生支持、且生产环境广泛使用的防护手段:
-
在
nginx.conf全局层级(stream { }外)定义共享内存区:stream { limit_conn_zone $binary_remote_addr zone=conn_per_ip:10m; limit_conn_zone $server_addr zone=total_conn:10m; } -
在具体
server块中启用限制:server { listen 8080; proxy_pass backend; limit_conn conn_per_ip 20; # 单 IP 最多 20 个并发连接 limit_conn total_conn 1000; # 本机监听端口总连接数 ≤ 1000 }
⚠️ 超限时 Nginx 直接发送 TCP RST 包拒绝新连接,无排队、无缓冲,响应快、开销低。
❌ 为什么不能像 HTTP 那样限带宽?
-
limit_rate、limit_rate_after等指令仅在http上下文生效,作用于 HTTP 响应体发送阶段; -
stream模块工作在传输层(L4),不解析应用层协议(如 HTTP 内容、文件体),因此无法对“上传数据流”做字节级速率控制; - 官方文档明确说明:
stream模块不提供任何基于速率(bytes/sec)的限速能力。
? 若确实需要 TCP 层带宽限制,可选替代方案
| 方案 | 说明 | 适用场景 |
|---|---|---|
Linux tc(Traffic Control) |
使用内核 qdisc(如 tbf、htb)对网卡或进程出口流量整形,支持按源 IP、端口精细限速 |
需要系统级权限;适合固定上行带宽管控(如限制某服务最大上传 5MB/s) |
| HAProxy(L4 mode) | 支持 tcp-request content + stick-table 实现连接级速率采样和限速 |
替代 Nginx stream,功能更丰富,支持连接+速率双重策略 |
| Envoy / Squid(TCP 模式) | Envoy 提供完整 L4 流量策略;Squid 支持 delay_pools 控制 TCP 流量 |
中大型架构,需统一网关能力 |
| 后端服务自身限速 | 在被代理的服务中实现 socket 发送节流(如 write() 速率控制、滑动窗口缓冲) |
后端可控、协议简单(如自研 TCP 服务) |
? 小提示:若实际代理的是 HTTP 流量(例如非标准端口的 API),建议改用
http模块反向代理,即可直接使用limit_rate控制响应下行速率(注意:仍无原生 upload 限速)。
? 配置验证要点
-
开启
stream日志确认限流生效:stream { log_format stream_log '$remote_addr [$time_local] $status'; access_log /var/log/nginx/stream.log stream_log; # ... 其他配置 }观察日志中
$status为503的条目,即表示limit_conn触发拒绝。 -
查看当前连接数:
ss -s | grep "TCP:" ss -tn state established '( dport = :8080 )' | wc -l
压测验证:用
ab -n 1000 -c 50 telnet://host:8080类工具模拟并发连接,观察失败率是否符合预期。
不复杂但容易忽略:TCP 代理的“限流”,本质是防连接风暴,不是控带宽。想控速率,得换工具或下沉到系统层。


















