1. 为什么需要四层代理?

你可能已经熟悉Nginx作为HTTP反向代理的用法,但它的能力远不止于此。当我们需要代理MySQL、Redis或游戏服务器这类非HTTP协议时,传统的七层代理就力不从心了。这就是四层代理的用武之地——它工作在传输层,直接处理TCP/UDP数据流,不关心应用层协议内容。

我遇到过这样一个实际场景:某电商平台需要将Redis请求均匀分发到多个节点。最初他们尝试用HTTP代理,结果发现性能低下且经常超时。改用Nginx的Stream模块后,不仅吞吐量提升了3倍,还能自动剔除故障节点。这种"透明管道"的特性,正是四层代理的核心价值。

与LVS等方案相比,Nginx Stream的优势在于:

  • 配置灵活:支持轮询、哈希、最小连接等多种算法
  • 精细控制:可设置超时时间、重试策略等参数
  • 易扩展:与现有Nginx生态无缝集成

2. Stream模块核心配置详解

2.1 基础模块结构

要让Nginx支持TCP/UDP代理,首先确认编译时包含--with-stream参数。配置文件通常分为三个部分:

worker_processes 4;
events {
    worker_connections 8192;
}
stream {
    upstream db_cluster {
        server 10.0.0.1:3306;
        server 10.0.0.2:3306;
    }
    server {
        listen 3306;
        proxy_pass db_cluster;
    }
}

关键点在于stream块与http块是平级关系。我曾见过有人错误地将stream配置嵌套在http块内,导致配置完全不生效。

2.2 负载均衡算法选择

根据业务特点选择合适算法:

  • 轮询(默认):适合各节点性能均衡的场景
  • 哈希:需要会话保持时使用,如hash $remote_addr
  • 最小连接:处理长连接服务的利器,用least_conn开启

实测发现,在WebSocket服务中使用最小连接算法,能有效避免某些节点过载的情况。

3. 高可用性实战技巧

3.1 健康检查机制

Nginx提供被动式健康检查,通过以下参数控制:

server 10.0.0.1:3306 max_fails=3 fail_timeout=30s;

这个配置意味着:30秒内失败3次就将节点标记为不可用,30秒后再重新尝试。我在生产环境中发现,对于数据库类服务,适当延长fail_timeout能避免因网络抖动导致的误判。

3.2 连接保持优化

TCP长连接需要特别注意:

proxy_timeout 1h;
proxy_socket_keepalive on;

配合系统内核参数调整:

sysctl -w net.ipv4.tcp_keepalive_time=600
sysctl -w net.ipv4.tcp_keepalive_intvl=30

曾经有个游戏服务器项目,因为没设置keepalive,导致玩家频繁掉线。加入这些配置后,连接稳定性显著提升。

4. 常见问题排查指南

4.1 连接超时问题

如果遇到connection timeout错误,检查这些参数:

  • proxy_connect_timeout:建议设置为5-10秒
  • proxy_timeout:根据业务特点调整
  • proxy_next_upstream:确保开启容错机制

4.2 性能调优建议

对于高并发场景:

  1. 增加worker_processesworker_connections
  2. 调整worker_rlimit_nofile限制
  3. 考虑使用reuseport选项提升性能
server {
    listen 3306 reuseport;
    # ...
}

在某个日活百万的社交App中,启用reuseport后QPS提升了约15%。

5. 典型应用场景配置

5.1 MySQL读写分离

stream {
    upstream mysql_read {
        server read1.example.com:3306;
        server read2.example.com:3306;
    }
    upstream mysql_write {
        server master.example.com:3306;
    }
    server {
        listen 3306;
        proxy_pass mysql_write;
    }
    server {
        listen 3307;
        proxy_pass mysql_read;
    }
}

5.2 Redis集群代理

upstream redis_nodes {
    hash $remote_addr consistent;
    server 192.168.1.10:6379;
    server 192.168.1.11:6379;
}

使用一致性哈希可以最大限度减少缓存失效。有个电商项目迁移到这种架构后,缓存命中率从82%提升到了97%。

6. 安全加固建议

6.1 访问控制列表

server {
    listen 3306;
    allow 10.0.0.0/24;
    deny all;
    proxy_pass db_cluster;
}

6.2 SSL终端代理

server {
    listen     443 ssl;
    proxy_pass backend;
    ssl_certificate     /path/to/cert.pem;
    ssl_certificate_key /path/to/key.pem;
}

在金融行业项目中,这种配置既保证了传输安全,又避免了每个后端节点单独配置证书的麻烦。

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐