在 Nginx 中,stream
模块和 http
模块是完全独立的两个模块,分别用于处理不同协议层的网络流量。以下是两者的核心区别、使用场景及配置示例:
一、核心区别
特性 | http 模块 |
stream 模块 |
---|---|---|
协议层 | 处理 HTTP/HTTPS(应用层,Layer 7) | 处理 TCP/UDP(传输层,Layer 4) |
功能支持 | 支持 URL 路由、Header 操作、缓存、SSL 终端等 | 仅代理原始 TCP/UDP 流量,不解析协议内容 |
负载均衡策略 | 基于 HTTP 请求头(如 Host、URI) | 基于 IP 地址、端口等传输层信息 |
典型用途 | Web 服务器、API 反向代理 | 数据库代理(如 MySQL)、TCP 负载均衡 |
二、stream
模块无法直接代理 HTTP 的原因
协议不兼容
stream
模块仅操作 TCP/UDP 流,无法解析 HTTP 请求头(如Host
、User-Agent
),也无法生成 HTTP 响应(如状态码、Header)。功能限制
• 不支持 HTTP 路由(如/api
转发到不同后端)。
• 无法处理 HTTPS 加密流量(需通过http
模块的 SSL 终端)。
三、正确使用 stream
和 http
的配置示例
场景 1:http
模块代理 HTTP 流量(推荐)
http {
upstream backend {
server 192.168.1.10:80;
server 192.168.1.11:80;
}
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://backend;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
}
功能:
• 解析 HTTP 请求,转发到后端服务器。
• 支持动态路由、Header 修改、SSL 终端等。
场景 2:stream
模块代理 TCP 流量(非 HTTP)
stream {
upstream tcp_backend {
server 192.168.1.20:3306; # MySQL
server 192.168.1.21:3306;
}
server {
listen 3306;
proxy_pass tcp_backend;
proxy_timeout 30s;
}
}
功能:
• 将 TCP 流量(如 MySQL)转发到后端服务器。
• 后端服务器需自行处理协议解析(如 MySQL 协议)。
四、常见误区与解决方案
误区:尝试用 stream
代理 HTTP
• 问题:后端服务器会收到原始 TCP 流,无法解析 HTTP 请求,导致服务不可用。
• 解决方案:
改用 http
模块,或通过 stream
代理到另一个支持 HTTP 的中间层(如 HAProxy)。
误区:混合配置 http
和 stream
• 注意:两者需在 Nginx 配置文件中并列定义,不能嵌套:
# 正确配置结构
http { ... }
stream { ... }
stream块配置与http块并列,在nginx.conf中配置,可以用include方式将我们配置实例单独配置,方便管理。
user nginx;
worker_processes 8;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
#vhost_traffic_status_zone;
include /etc/nginx/conf.d/*.conf;
access_log /var/log/nginx/access.log;
}
stream {
log_format debug '$remote_addr [$time_local] '
'$protocol $status $bytes_sent $bytes_received '
'$session_time "$upstream_addr" '
'"$upstream_bytes_sent" "$upstream_bytes_received" "$upstream_connect_time"';
access_log /var/log/nginx/tcp-access.log debug;
include /etc/nginx/conf.d/*.stream;
}
五、何时选择 stream
?
- 非 HTTP 协议代理:如 MySQL、Redis、DNS(UDP)。
- 传输层负载均衡:需基于 IP/端口分发流量。
- SSL 终端:解密 TCP 加密流量后转发。
总结
• HTTP 流量:必须使用 http
模块。
• TCP/UDP 流量:使用 stream
模块。
• 混合场景:可通过多进程或分层代理(如 Nginx + HAProxy)实现。
如需进一步优化配置(如 SSL 终端、健康检查),可参考具体模块的官方网页。