Nginx 不支持单 upstream 混合多协议,必须分层部署:HTTP/HTTPS 用 http 块(七层),TCP/UDP 用 stream 块(四层),二者同级隔离、共存于同一实例,共享端口但独立运行,不可混配或嵌套。

Nginx 本身不支持单个 upstream 组混合转发 HTTP、HTTPS、TCP、UDP 等多种协议——因为协议处理层级不同,必须用不同模块隔离配置。要实现“多协议混合转发的高性能代理集群”,核心是**分层部署 + 模块分工**:HTTP/HTTPS 走 http 块(七层),TCP/UDP 走 stream 块(四层),两者共存于同一 Nginx 实例,共享监听端口能力,但完全独立运行。
明确区分 http 和 stream 两大配置域
Nginx 的 http 模块处理应用层协议(如 HTTP/1.1、HTTP/2、gRPC、WebSocket),可做 URL 路由、Header 改写、SSL 终止等;stream 模块处理传输层协议(TCP/UDP),只做连接级转发,不解析内容,性能更高。二者不能混用,也不能在同一个 server 块里定义多协议 proxy_pass。
- http 块负责:Web 流量(80/443)、API(/api/v1)、静态资源、gRPC over HTTP/2
- stream 块负责:数据库(MySQL:3306、PostgreSQL:5432)、邮件(SMTP:25)、自定义 TCP 服务(如 IoT 设备长连接)、UDP DNS 查询(需启用 udp)
配置示例:共用一台 Nginx,支撑 HTTP + MySQL + DNS 混合代理
在 /etc/nginx/nginx.conf 中并列定义 http 和 stream 块(注意:stream 必须在 http 外层,且不能嵌套):
# —— stream 块:四层 TCP/UDP 转发(放在 http 块之外)
stream {
# MySQL 代理(TCP)
upstream mysql_backend {
server 192.168.2.10:3306 max_fails=3 fail_timeout=30s;
server 192.168.2.11:3306 backup;
}
server {
listen 3306;
proxy_pass mysql_backend;
proxy_timeout 1h;
proxy_responses 1;
}
<pre class="brush:php;toolbar:false;"># DNS 查询代理(UDP,需 Nginx ≥ 1.9.13)
upstream dns_backend {
server 192.168.2.20:53;
server 192.168.2.21:53;
}
server {
listen 53 udp;
proxy_pass dns_backend;
proxy_timeout 5s;
}}
—— http 块:七层 Web 与 API 代理
http { upstream web_servers { server 192.168.1.100:8080 weight=3; server 192.168.1.101:8080 weight=2; ip_hash; # 保证登录态一致 }
upstream api_servers {
server 192.168.1.200:9000;
least_conn;
}
server {
listen 80;
server_name app.example.com;
location / {
proxy_pass http://web_servers;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
location /api/ {
proxy_pass http://api_servers;
}
}}
关键性能与可靠性保障点
多协议混合场景下,光配通不够,必须针对性调优:
-
连接复用与超时控制:stream 模块用
proxy_timeout(非 proxy_read_timeout),http 模块用proxy_connect_timeout/proxy_send_timeout分别控制建连、发包、收包阶段,避免僵死连接堆积 -
健康检查差异化:http 层可用
health_check(需 Plus)或配合第三方模块(如 nginx_upstream_check_module);stream 层仅支持基础max_fails/fail_timeout,不支持 HTTP 状态码探测 -
资源隔离:为 stream 和 http 分别设置
worker_connections上限,并通过events { use epoll; worker_connections 10240; }启用高效 I/O 模型 - SSL 卸载位置:HTTPS 解密必须在 http 块完成(用 ssl_certificate);TCP 层的 TLS 流量(如 MySQL over SSL)应透传,Nginx 不解密,否则破坏协议语义
扩展建议:协议识别与智能路由(进阶)
若需更灵活的“协议感知”转发(例如:同一 443 端口区分 HTTPS 流量和 TLS 封装的 gRPC 或 MQTT),纯开源 Nginx 不支持 ALPN 或 SNI 深度识别。此时可:
- 用
stream+ssl_preread指令提取 SNI 域名,实现基于域名的 TCP 分流(适用于多个 HTTPS 站点或 gRPC 服务) - 引入 OpenResty + Lua,在
init_by_lua_block或access_by_lua_block中解析 TLS ClientHello,做协议预判(需较强开发能力) - 对高复杂度场景,建议前置专用四层网关(如 Envoy 或 Traefik),让 Nginx 专注七层优化











