欢迎光临中国葬花网
详情描述
Nginx Stream模块详细攻略:四层代理的艺术与实践

一、Stream模块概述

1.1 什么是四层代理

  • OSI模型:工作在传输层(TCP/UDP)
  • 与七层代理区别
    • 四层:基于IP+端口转发,不解析应用层协议
    • 七层:基于HTTP等应用层协议解析转发
  • 优势:性能更高、支持非HTTP协议、连接保持

1.2 Stream模块特性

  • 从Nginx 1.9.0开始支持
  • 独立于HTTP模块的配置上下文
  • 支持TCP和UDP负载均衡
  • 支持SSL/TLS终端代理
  • 连接数限制和超时控制

二、核心配置详解

2.1 基础配置结构

# 主配置文件 nginx.conf
events {
    worker_connections 1024;
}

# Stream模块配置块
stream {
    # 共享配置
    log_format proxy '$remote_addr [$time_local] '
                     '$protocol $status $bytes_sent $bytes_received '
                     '$session_time "$upstream_addr"';

    access_log /var/log/nginx/stream-access.log proxy;

    # 上游服务器组
    upstream backend_tcp {
        zone backend_tcp 64k;
        server 192.168.1.10:3306 weight=3;
        server 192.168.1.11:3306 weight=2;
        server 192.168.1.12:3306 weight=1 backup;
    }

    upstream backend_udp {
        server 192.168.1.20:53;
        server 192.168.1.21:53;
    }

    # TCP服务配置
    server {
        listen 3306;
        proxy_pass backend_tcp;
        proxy_connect_timeout 3s;
        proxy_timeout 1h;

        # SSL透传或终止
        # ssl_preread on;
        # proxy_ssl on;
    }

    # UDP服务配置
    server {
        listen 53 udp reuseport;
        proxy_pass backend_udp;
        proxy_timeout 3s;
        proxy_responses 1;
    }

    # 负载均衡算法示例
    upstream lb_example {
        # 轮询(默认)
        server 192.168.1.30:6379;

        # 最少连接数
        least_conn;
        server 192.168.1.31:6379;

        # Hash
        hash $remote_addr consistent;
        server 192.168.1.32:6379;
    }
}

2.2 关键指令解析

2.2.1 监听配置
# TCP监听
listen 1935;                          # 默认TCP
listen 1935 ssl;                      # TCP+SSL
listen 1935 http2;                    # HTTP/2
listen [::1]:1935 ipv6only=on;        # IPv6

# UDP监听
listen 53 udp;                        # UDP协议
listen 53 udp reuseport;              # 端口重用(提升性能)

# 参数说明:
# reuseport - Linux 3.9+,多个worker独立socket,减少锁竞争
# so_keepalive - TCP keepalive
# backlog - 连接队列大小
2.2.2 代理指令
proxy_pass upstream_name;             # 转发到上游组
proxy_pass 192.168.1.100:8080;        # 直接转发

# 超时控制
proxy_connect_timeout 10s;           # 连接上游超时
proxy_timeout 24h;                   # 连接空闲超时
proxy_upload_rate 100k;              # 上传速率限制
proxy_download_rate 1m;              # 下载速率限制

# 缓冲控制
proxy_buffer_size 16k;               # 缓冲区大小
2.2.3 SSL/TLS处理
# SSL终止(解密后再转发)
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;
}

# SSL透传(不解密直接转发)
server {
    listen 443;
    ssl_preread on;                    # 预读SSL信息
    proxy_pass $ssl_preread_server_name;  # 基于SNI转发
}

# 上游SSL加密
proxy_ssl on;
proxy_ssl_certificate /path/to/client.crt;
proxy_ssl_certificate_key /path/to/client.key;
proxy_ssl_protocols TLSv1.2 TLSv1.3;
proxy_ssl_verify on;
proxy_ssl_trusted_certificate /path/to/ca.crt;

三、高级应用场景

3.1 数据库负载均衡

stream {
    upstream mysql_masters {
        zone mysql_masters 64k;
        server db1.example.com:3306 weight=5;
        server db2.example.com:3306 weight=3;
        server db3.example.com:3306 weight=2;
    }

    upstream mysql_slaves {
        least_conn;
        server slave1.example.com:3306;
        server slave2.example.com:3306;
        server slave3.example.com:3306;
    }

    # 读写分离(基于端口)
    server {
        listen 3307;  # 读端口
        proxy_pass mysql_slaves;
        proxy_connect_timeout 3s;
    }

    server {
        listen 3308;  # 写端口
        proxy_pass mysql_masters;
        proxy_connect_timeout 3s;
    }

    # 健康检查
    match mysql_check {
        send "\x00\x00\x00\x0a\x40\x00\x00\x00\x00\x00\x00\x00";
        expect ~* "MySQL";
    }
}

3.2 Redis集群代理

stream {
    # 一致性Hash分片
    upstream redis_shard_0 {
        server 192.168.1.100:6379;
    }
    upstream redis_shard_1 {
        server 192.168.1.101:6379;
    }

    server {
        listen 6379;

        # 基于key分片
        set $redis_shard $arg_key;
        hash $redis_shard consistent;

        location @shard_0 {
            proxy_pass redis_shard_0;
        }
        location @shard_1 {
            proxy_pass redis_shard_1;
        }
    }
}

3.3 SSH跳板机

stream {
    # SSH访问控制
    map $remote_addr $allow_ssh {
        default 0;
        10.0.0.0/8 1;
        192.168.0.0/16 1;
    }

    server {
        listen 22;

        # IP白名单
        if ($allow_ssh = 0) {
            return;
        }

        # 基于用户名的路由
        proxy_ssl_preread on;
        ssl_preread on;

        # SSH协议解析
        preread_buffer_size 1k;

        proxy_pass ssh_backend;
    }

    upstream ssh_backend {
        server 10.1.1.100:22;
        server 10.1.1.101:22 backup;
    }
}

3.4 游戏服务器代理

stream {
    # UDP游戏服务器
    upstream game_servers {
        server 10.0.1.100:7777;
        server 10.0.1.101:7777;
    }

    server {
        listen 7777 udp reuseport;
        proxy_pass game_servers;
        proxy_timeout 10s;

        # 会话保持
        hash $remote_addr consistent;
    }

    # 状态统计
    server {
        listen 8080;
        return 200 "Active connections: $connections\n";
    }
}

四、性能优化与监控

4.1 性能调优参数

stream {
    # 全局配置
    worker_processes auto;                    # CPU核心数
    worker_rlimit_nofile 65535;              # 文件描述符限制

    # 事件模块
    events {
        use epoll;                           # Linux推荐
        worker_connections 20480;            # 每个worker连接数
        multi_accept on;
    }

    # TCP优化
    tcp_nodelay on;                          # 禁用Nagle算法
    tcp_nopush on;

    # 缓冲区优化
    proxy_buffer_size 4k;
    proxy_buffers 8 4k;

    # 连接池
    resolver 8.8.8.8 valid=30s;
    resolver_timeout 3s;
}

4.2 健康检查配置

stream {
    # 主动健康检查
    upstream backend {
        zone backend 64k;
        server 192.168.1.10:3306 max_fails=3 fail_timeout=30s;
        server 192.168.1.11:3306 max_fails=3 fail_timeout=30s;

        # 定制检查
        match tcp_check {
            send "PING\r\n";
            expect ~* "PONG";
            interval 10s;
            passes 2;
            fails 3;
        }
    }

    # 被动健康检查
    server {
        proxy_pass backend;
        proxy_next_upstream on;
        proxy_next_upstream_timeout 0;
        proxy_next_upstream_tries 2;
    }
}

4.3 监控与日志

stream {
    # 自定义日志格式
    log_format stream_detail '$remote_addr - $remote_user [$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/stream.log stream_detail buffer=32k flush=5s;
    error_log /var/log/nginx/stream_error.log warn;

    # 状态统计
    server {
        listen 8081;
        return 200 "
Upstream: $upstream_addr\n
Status: $status\n
Session Time: $session_time\n
Bytes Sent: $bytes_sent\n
Bytes Received: $bytes_received\n
";
    }
}

五、安全加固

5.1 访问控制

stream {
    # IP白名单
    allow 192.168.1.0/24;
    allow 10.0.0.0/8;
    deny all;

    # 连接限制
    limit_conn_zone $binary_remote_addr zone=conn_limit:10m;

    server {
        listen 3306;
        limit_conn conn_limit 10;           # 每个IP最多10个连接
        limit_conn_status 444;              # 关闭连接不响应

        # 速率限制
        proxy_upload_rate 100k;
        proxy_download_rate 500k;
    }

    # GeoIP限制
    geo $deny_country {
        default 0;
        CN 1;  # 允许中国
        US 1;  # 允许美国
    }

    server {
        if ($deny_country = 0) {
            return;
        }
    }
}

5.2 SSL安全配置

stream {
    server {
        listen 443 ssl;

        # 强密码套件
        ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384';
        ssl_prefer_server_ciphers on;

        # 安全协议
        ssl_protocols TLSv1.2 TLSv1.3;

        # HSTS
        add_header Strict-Transport-Security "max-age=31536000" always;

        # OCSP Stapling
        ssl_stapling on;
        ssl_stapling_verify on;

        proxy_pass backend;
    }
}

六、实战案例:MySQL高可用代理

# mysql-proxy.conf
stream {
    # 日志配置
    log_format mysql_log '$remote_addr [$time_local] "$protocol" '
                        'upstream: $upstream_addr '
                        'bytes: $bytes_sent/$bytes_received '
                        'time: $upstream_connect_time/$session_time';

    access_log /var/log/nginx/mysql-proxy.log mysql_log;

    # 健康检查
    match mysql_health {
        # MySQL ping包
        send "\x0a\x00\x00\x00\x0a\x53\x45\x4c\x45\x43\x54\x20\x31\x00";
        expect ~* "MySQL";
        interval 5s;
        passes 2;
        fails 3;
    }

    # 主库组
    upstream mysql_master {
        zone mysql_master 64k;
        server 192.168.1.100:3306 max_fails=3 fail_timeout=30s;
        server 192.168.1.101:3306 backup;
    }

    # 从库组
    upstream mysql_slave {
        zone mysql_slave 64k;
        least_conn;
        server 192.168.1.102:3306 weight=3;
        server 192.168.1.103:3306 weight=2;
        server 192.168.1.104:3306 weight=1;
    }

    # 写端口
    server {
        listen 3306;

        # 连接限制
        limit_conn mysql_conn 50;

        # 超时设置
        proxy_connect_timeout 2s;
        proxy_timeout 3600s;

        # 失败重试
        proxy_next_upstream on;
        proxy_next_upstream_timeout 1s;
        proxy_next_upstream_tries 2;

        proxy_pass mysql_master;

        # 监控端点
        status_zone mysql_master_proxy;
    }

    # 读端口
    server {
        listen 3307;

        # 会话保持(同一客户端路由到同一从库)
        hash $remote_addr consistent;

        proxy_pass mysql_slave;

        # 监控端点
        status_zone mysql_slave_proxy;
    }

    # 管理端口
    server {
        listen 8080;

        location /status {
            stream_status;
            access_log off;
        }

        location /stats {
            prometheus;
            access_log off;
        }
    }
}

七、故障排查与调试

7.1 常用调试方法

# 1. 检查配置
nginx -t -c /etc/nginx/nginx.conf

# 2. 调试模式运行
nginx -g "daemon off; error_log stderr debug;"

# 3. 连接测试
nc -zv proxy_host 3306
telnet proxy_host 3306

# 4. 查看连接状态
ss -tnp | grep nginx
netstat -tnp | grep nginx

# 5. 实时日志监控
tail -f /var/log/nginx/stream-access.log
tail -f /var/log/nginx/error.log

# 6. 性能监控
nginx -T | grep stream  # 查看完整配置

7.2 常见问题解决

连接超时

proxy_connect_timeout 5s;
proxy_timeout 300s;

连接数限制

worker_rlimit_nofile 65535;
events {
    worker_connections 20480;
}

内存不足

proxy_buffer_size 4k;
proxy_buffers 8 4k;

八、最佳实践总结

架构设计

  • 四层代理用于性能敏感、协议无关的场景
  • 七层代理用于需要内容感知的场景

安全建议

  • 最小化开放端口
  • 实施IP白名单
  • 启用连接限制
  • 定期更新Nginx

性能优化

  • 使用reuseport减少锁竞争
  • 调整缓冲区大小
  • 启用TCP优化参数
  • 监控连接池状态

高可用

  • 多节点部署
  • 健康检查配置
  • 故障自动切换
  • 配置版本管理

监控告警

  • 连接数监控
  • 响应时间监控
  • 错误率监控
  • 资源使用监控

通过合理使用Nginx Stream模块,可以构建高性能、高可用的四层代理服务,满足数据库、游戏、实时通信等各种场景的需求。

相关帖子
在异地提交了换证申请后,因故需要取消或修改信息该如何操作?
在异地提交了换证申请后,因故需要取消或修改信息该如何操作?
基于Python实现桌面动态文字壁纸的详细步骤
基于Python实现桌面动态文字壁纸的详细步骤
如果对节能补贴的审核结果有异议,2026年可以通过哪些渠道反馈?
如果对节能补贴的审核结果有异议,2026年可以通过哪些渠道反馈?
襄阳市网站制作设计#搜索引擎优化,多年建站经验
襄阳市网站制作设计#搜索引擎优化,多年建站经验
襄阳市一条龙殡葬服务办理|白事一条龙办理,白事仪式
襄阳市一条龙殡葬服务办理|白事一条龙办理,白事仪式
山南市网站优化公司#精准获客助手,模板建站
山南市网站优化公司#精准获客助手,模板建站
农业遥感如何帮助农民了解作物长势并预估产量,2026年有哪些新应用?
农业遥感如何帮助农民了解作物长势并预估产量,2026年有哪些新应用?
在选择医保定点药店时,我们应该重点考虑和对比哪些因素?
在选择医保定点药店时,我们应该重点考虑和对比哪些因素?
为什么说智能水表和电表的数据,正在成为评估个人信用的潜在依据?
为什么说智能水表和电表的数据,正在成为评估个人信用的潜在依据?
南充市安卓系统app开发@品牌网站定制开发,专业建站
南充市安卓系统app开发@品牌网站定制开发,专业建站
恋爱期间共同出资买房但未结婚,房产的归属问题应该如何妥善处理?
恋爱期间共同出资买房但未结婚,房产的归属问题应该如何妥善处理?
如果未来想买下政府持有的产权份额,具体的评估和购买流程是怎样的?
如果未来想买下政府持有的产权份额,具体的评估和购买流程是怎样的?
在2026年,面对越来越逼真的AI生成内容,我们该如何保持警惕?
在2026年,面对越来越逼真的AI生成内容,我们该如何保持警惕?
员工主动辞职时,当年未休的年休假工资应该如何正确计算和支付?
员工主动辞职时,当年未休的年休假工资应该如何正确计算和支付?
2026年想将家里的高额宽带套餐降级,运营商却设置重重障碍该怎么办?
2026年想将家里的高额宽带套餐降级,运营商却设置重重障碍该怎么办?
汉中市正规殡葬公司|丧葬服务公司,搭设灵堂
汉中市正规殡葬公司|丧葬服务公司,搭设灵堂
在停工停课期间,企业是否有权安排员工使用带薪年假或其他假期?
在停工停课期间,企业是否有权安排员工使用带薪年假或其他假期?
延安市网站建设推广服务#外贸网站建设,高端网站开发设计
延安市网站建设推广服务#外贸网站建设,高端网站开发设计
如果用人单位拒绝发放高温津贴,作为普通员工应该如何有效维权?
如果用人单位拒绝发放高温津贴,作为普通员工应该如何有效维权?