NGINX TCP/UDP Stream 模块指南
1. Stream 模块概述
Stream 模块提供 TCP/UDP 流处理功能,包括:
- TCP 代理与负载均衡
- UDP 代理(DNS、日志收集等)
- TLS/SSL 终端
- 基于 SNI 的路由
版本要求
- 自 1.9.0 版本可用
- 默认不构建,需编译时添加
--with-stream 参数
配置上下文
stream {
# TCP/UDP 配置
server {
listen 12345;
proxy_pass backend:54321;
}
}
2. 基础配置示例
TCP 代理
stream {
upstream backend {
server 192.168.1.1:3306;
server 192.168.1.2:3306;
}
server {
listen 3306;
proxy_pass backend;
proxy_timeout 3s;
proxy_connect_timeout 1s;
}
}
UDP 代理
stream {
upstream dns_servers {
server 8.8.8.8:53;
server 8.8.4.4:53;
}
server {
listen 53 udp;
proxy_pass dns_servers;
proxy_timeout 20s;
}
}
Unix Socket 代理
stream {
server {
listen unix:/tmp/stream.sock;
proxy_pass unix:/tmp/backend.sock;
}
}
3. 负载均衡
配置示例
stream {
upstream mysql_backend {
hash $remote_addr consistent; # 一致性哈希
server mysql1:3306 weight=5;
server mysql2:3306;
server mysql3:3306 backup;
}
server {
listen 3306;
proxy_pass mysql_backend;
}
}
负载均衡算法
| 算法 |
指令 |
说明 |
| 轮询 |
默认 |
加权轮询 |
| 最少连接 |
least_conn; |
连接数最少优先 |
| 哈希 |
hash key [consistent]; |
基于键哈希 |
server 参数
| 参数 |
说明 |
weight=N |
权重 |
max_conns=N |
最大连接数 |
max_fails=N |
失败次数阈值 |
fail_timeout=T |
失败统计时间 |
backup |
备份服务器 |
down |
标记不可用 |
resolve |
解析域名 IP 变化 |
4. 核心指令
listen 指令
server {
listen 80; # TCP
listen 53 udp; # UDP
listen 443 ssl; # TLS
listen 12345 udp reuseport; # UDP + reuseport
listen [::]:80; # IPv6
listen unix:/tmp/stream.sock; # Unix Socket
}
参数说明:
| 参数 |
说明 |
ssl |
启用 SSL |
udp |
UDP 协议 |
reuseport |
每个 worker 独立监听 |
proxy_protocol |
启用 PROXY 协议 |
backlog=N |
连接队列长度 |
so_keepalive |
TCP keepalive |
proxy_pass 指令
server {
listen 3306;
proxy_pass 192.168.1.1:3306;
proxy_pass backend;
proxy_pass $upstream;
}
超时配置
server {
proxy_timeout 10m; # 客户端/后端之间读写超时(默认 10m)
proxy_connect_timeout 60s; # 连接后端超时(默认 60s)
}
缓冲配置
server {
proxy_buffer_size 16k; # 读写缓冲区大小(默认 16k)
}
5. SSL/TLS 配置
服务端 SSL
stream {
server {
listen 443 ssl;
ssl_certificate /path/to/cert.pem;
ssl_certificate_key /path/to/key.pem;
ssl_protocols TLSv1.2 TLSv1.3;
proxy_pass backend:8080;
}
}
上游 SSL(连接后端使用 SSL)
server {
listen 3306;
proxy_pass backend:3306;
proxy_ssl on;
proxy_ssl_protocols TLSv1.2 TLSv1.3;
proxy_ssl_verify on;
proxy_ssl_trusted_certificate /path/to/ca.pem;
proxy_ssl_server_name on;
}
SSL 配置指令
| 指令 |
说明 |
ssl_certificate |
证书文件 |
ssl_certificate_key |
私钥文件 |
ssl_protocols |
启用的协议 |
ssl_ciphers |
加密套件 |
ssl_session_cache |
会话缓存 |
proxy_ssl |
启用上游 SSL |
proxy_ssl_verify |
验证上游证书 |
proxy_ssl_server_name |
启用 SNI |
6. 基于名称的虚拟服务器(SNI)
版本要求:1.25.5+
stream {
map $ssl_server_name $backend {
app1.example.com app1_backend;
app2.example.com app2_backend;
default default_backend;
}
upstream app1_backend {
server 192.168.1.1:8080;
}
upstream app2_backend {
server 192.168.1.2:8080;
}
server {
listen 443 ssl;
server_name app1.example.com app2.example.com;
ssl_certificate /path/to/cert.pem;
ssl_certificate_key /path/to/key.pem;
proxy_pass $backend;
}
}
7. PROXY 协议
接收 PROXY 协议
server {
listen 3306 proxy_protocol;
proxy_pass backend:3306;
}
发送 PROXY 协议
server {
listen 3306;
proxy_protocol on;
proxy_pass backend:3306;
}
PROXY 协议变量
| 变量 |
说明 |
$proxy_protocol_addr |
客户端 IP |
$proxy_protocol_port |
客户端端口 |
$proxy_protocol_server_addr |
服务器 IP |
$proxy_protocol_server_port |
服务器端口 |
8. 速率限制
server {
listen 3306;
proxy_pass backend:3306;
proxy_download_rate 1m; # 限制从后端读取速率(字节/秒)
proxy_upload_rate 1m; # 限制从客户端读取速率(字节/秒)
}
使用变量动态限制:
map $remote_addr $limit_rate {
default 1m;
10.0.0.1 10m; # 特定 IP 更高速率
}
server {
proxy_download_rate $limit_rate;
proxy_upload_rate $limit_rate;
}
9. 故障转移
server {
listen 3306;
proxy_pass backend:3306;
proxy_next_upstream on; # 连接失败时尝试下一台
proxy_next_upstream_timeout 30s; # 总时间限制
proxy_next_upstream_tries 3; # 尝试次数限制
}
10. 连接保持
upstream backend {
server 192.168.1.1:3306;
keepalive 32; # 保持 32 个空闲连接
keepalive_timeout 60s; # 空闲连接超时
keepalive_requests 1000; # 单个连接最大请求数
}
11. 内置变量
| 变量 |
说明 |
$remote_addr |
客户端 IP |
$remote_port |
客户端端口 |
$server_addr |
服务器 IP |
$server_port |
服务器端口 |
$protocol |
协议(TCP/UDP) |
$bytes_received |
接收字节数 |
$bytes_sent |
发送字节数 |
$session_time |
会话时间(秒) |
$status |
会话状态 |
$ssl_preread_server_name |
SNI 名称 |
12. 应用场景示例
MySQL 代理
stream {
upstream mysql_servers {
least_conn;
server mysql1:3306 weight=5;
server mysql2:3306;
server mysql3:3306 backup;
}
server {
listen 3306;
proxy_pass mysql_servers;
proxy_timeout 600s;
proxy_connect_timeout 2s;
}
}
Redis 代理
stream {
upstream redis_servers {
server redis1:6379;
server redis2:6379;
}
server {
listen 6379;
proxy_pass redis_servers;
proxy_timeout 300s;
}
}
DNS 代理
stream {
upstream dns_servers {
server 8.8.8.8:53;
server 8.8.4.4:53;
}
server {
listen 53 udp reuseport;
proxy_pass dns_servers;
proxy_timeout 20s;
proxy_responses 1; # 期望 1 个响应
}
}
日志收集(Syslog)
stream {
upstream syslog_servers {
server syslog1:514;
server syslog2:514;
}
server {
listen 514 udp;
proxy_pass syslog_servers;
proxy_timeout 10s;
}
}
WebSocket 代理(TCP 层)
stream {
upstream websocket_servers {
server ws1:8080;
server ws2:8080;
}
server {
listen 8080;
proxy_pass websocket_servers;
proxy_timeout 3600s; # 长连接超时
}
}
13. 日志配置
stream {
log_format main '$remote_addr [$time_local] '
'$protocol $status $bytes_sent $bytes_received '
'$session_time "$upstream_addr"';
access_log /var/log/nginx/stream.log main;
server {
listen 3306;
proxy_pass backend:3306;
}
}
14. 健康检查
被动检查(内置)
upstream backend {
server 192.168.1.1:3306 max_fails=3 fail_timeout=30s;
server 192.168.1.2:3306 max_fails=3 fail_timeout=30s;
}
主动检查(NGINX Plus)
upstream backend {
zone backend 64k;
server 192.168.1.1:3306;
server 192.168.1.2:3306;
health_check interval=5s passes=2 fails=3;
health_check_timeout 5s;
}