nginx 的 stream 模块用于四层 tcp/udp 流量转发,不解析应用层协议,需在顶层作用域配置,支持 upstream 转发、超时控制、日志记录及基础监控。

nginx 的 stream 模块用于实现四层(传输层)TCP/UDP 流量转发,不解析应用层协议,直接透传原始字节流。它适合 MySQL、Redis、SSH、自定义 TCP 服务等非 HTTP 场景,核心是监听端口 + 转发到上游服务器。
确认模块已启用
stream 模块不是默认开启的,需验证是否编译进 nginx:
- 运行 nginx -V 2>&1 | grep with-stream,输出含 --with-stream 即支持
- 若无输出,需重新编译 nginx 并添加 --with-stream 参数;部分发行版(如 Ubuntu 22.04+ 官方包)已内置
- 不能在 http 块内配置 stream,否则报错 unknown directive "stream"
基础 TCP 代理配置结构
配置必须放在顶层作用域(与 http 同级),推荐拆分管理:
- 主配置 /etc/nginx/nginx.conf 中添加:
stream {
include /etc/nginx/stream.d/*.conf;
} - 新建目录 /etc/nginx/stream.d/,按业务建独立 conf 文件(如 mysql.conf)
- 每个 conf 文件包含 upstream 和 server 块,例如转发本地 3307 到内网 MySQL:
server 192.168.1.100:3306;
}
server {
listen 3307;
proxy_pass mysql_backend;
proxy_timeout 30s;
}
关键代理行为控制参数
stream 模块提供多个指令精细控制连接生命周期和转发逻辑:
- proxy_timeout:客户端空闲超时时间(单位秒),默认 6s;设为 0 表示永不过期,但建议按业务设置合理值
- proxy_responses:限制转发响应包数量,设为 1 可用于请求-响应型协议(如某些认证服务),收到首个响应即断连
- proxy_buffer_size:缓冲区大小,默认 8k;对高吞吐流(如 MySQL binlog)可调大至 64k 或更高
- proxy_bind:指定出口网卡 IP,适用于多网卡环境或需固定源地址的场景
日志与状态监控的实用组合
stream 不提供 HTTP 级别的 status_code 或建立耗时,但可通过组合方式逼近可观测性:
- 用 log_format 记录基础连接信息:
log_format stream_log "$time_iso8601 $remote_addr → $upstream_addr $bytes_sent $bytes_received";
access_log /var/log/nginx/stream-access.log stream_log; - 通过 error_log 捕获连接终态异常:
设置 proxy_timeout 后超时会记 upstream timed out;
后端拒绝连接记 connection refused;
客户端中断记 connection reset by peer - 真实 TCP 握手时长(SYN→SYN-ACK)需外部工具:用 tcpdump -ttt port XXXX 抓包计算,或在 upstream 服务侧 accept() 打点对比 nginx 的 $time_iso8601











