27.nginx中stream块跟http块的区别

在 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 的原因

  1. 协议不兼容
    stream 模块仅操作 TCP/UDP 流,无法解析 HTTP 请求头(如 HostUser-Agent),也无法生成 HTTP 响应(如状态码、Header)。

  2. 功能限制
    • 不支持 HTTP 路由(如 /api 转发到不同后端)。
    • 无法处理 HTTPS 加密流量(需通过 http 模块的 SSL 终端)。


三、正确使用 streamhttp 的配置示例

场景 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)。

误区:混合配置 httpstream

注意:两者需在 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

  1. 非 HTTP 协议代理:如 MySQL、Redis、DNS(UDP)。
  2. 传输层负载均衡:需基于 IP/端口分发流量。
  3. SSL 终端:解密 TCP 加密流量后转发。

总结

HTTP 流量:必须使用 http 模块。
TCP/UDP 流量:使用 stream 模块。
混合场景:可通过多进程或分层代理(如 Nginx + HAProxy)实现。

如需进一步优化配置(如 SSL 终端、健康检查),可参考具体模块的官方网页。

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容