Nginx 11月前

Nginx 四层代理详解:原理、配置与实战

作者头像 刘宇帅
2763 0

Nginx 除了强大的七层 HTTP 反向代理能力,还支持四层代理(TCP/UDP),可以胜任数据库、Redis、MQTT 等非 HTTP 服务的代理与负载均衡需求。

本文将全面讲解 Nginx 四层代理的工作机制、配置方法及常见使用场景,帮助你更灵活地管理底层服务连接。

目录

一、什么是四层代理

四层代理工作在 OSI 网络模型的传输层,主要转发 TCP 或 UDP 流量,不会解析应用层协议数据。

相比七层代理(如 HTTP 代理会读写 header、path),四层代理更加通用,适用于所有基于 TCP/UDP 的服务,例如:

  • MySQL 数据库
  • Redis 缓存
  • WebSocket
  • FTP 服务
  • DNS(UDP)

二、Nginx 如何支持四层代理

Nginx 的四层代理能力由 ngx_stream_core_module 模块提供,该模块从 Nginx 1.9.0 开始引入,1.11.0 起默认启用。

你可以使用以下命令检查是否支持:

nginx -V 2>&1 | grep --color stream

如果看到 --with-stream,说明已启用;否则需自行编译添加 --with-stream 参数。

四层代理使用 stream 区块配置,不放在 http 块中。

三、常见使用场景

  • TCP 端口转发(如将 3307 转发到 MySQL 3306)
  • 对 Redis、MySQL 实现负载均衡
  • 为内网服务统一代理出口
  • 转发 UDP 协议请求(如 DNS)
  • WebSocket 前置代理(比 HTTP 更低一层)
  • 容器或微服务环境下 TCP 服务暴露与集中管理

四、基础配置示例

下面是一个将本地 3307 端口转发到内网 MySQL 3306 的示例:

stream {
    server {
        listen 3307;
        proxy_pass 192.168.1.100:3306;
    }
}

说明:

  • 客户端连接 Nginx 的 3307 端口
  • Nginx 将请求原样转发到 192.168.1.100:3306
  • 所有 TCP 层数据不经解析,保持完整性

五、进阶配置技巧

多服务代理

支持多个端口监听,不同端口转发不同后端:

stream {
    server {
        listen 6379;
        proxy_pass 192.168.1.101:6379;
    }

    server {
        listen 3306;
        proxy_pass 192.168.1.102:3306;
    }
}

TCP 负载均衡

可使用 upstream 实现负载均衡:

stream {
    upstream mysql_cluster {
        server 10.0.0.2:3306;
        server 10.0.0.3:3306;
    }

    server {
        listen 3307;
        proxy_pass mysql_cluster;
    }
}

UDP 转发示例

适用于 DNS、VoIP 等 UDP 协议:

stream {
    server {
        listen 53 udp;
        proxy_pass 8.8.8.8:53;
    }
}

注意 UDP 使用需指明 udp 参数。

设置连接超时

合理设置连接时长,避免长连接占用资源:

proxy_connect_timeout 5s;
proxy_timeout 300s;

六、完整案例:Redis 四层代理

以下是一个 Redis 高可用代理配置,Nginx 监听 6379,转发到两台后端 Redis 实例:

stream {
    upstream redis_backend {
        server 10.1.1.10:6379;
        server 10.1.1.11:6379;
    }

    server {
        listen 6379;
        proxy_pass redis_backend;
        proxy_connect_timeout 3s;
        proxy_timeout 180s;
    }
}

你只需要连接本机的 6379 端口,即可自动分发到 Redis 后端。

七、常见问题排查

Nginx 配置四层代理时,如果出现问题,可从以下几点排查:

  • 启动时报错 unknown directive stream:未启用 --with-stream 模块
  • 配置写在 http 块内:stream 必须在 http 外层单独使用
  • 请求连接后卡住或断开:后端未监听目标端口或被防火墙拦截
  • 日志无输出:stream 模块日志需单独开启 log 模块或在 error.log 查看
  • 使用 systemd 启动失败:可能权限不足或端口冲突

总结

Nginx 的四层代理功能极大拓展了它在非 HTTP 场景下的适用性,特别适合处理 TCP 和 UDP 服务的转发与负载均衡。相比使用 HAProxy 或 LVS,Nginx 的配置更轻量、易用,适合快速上线和服务编排。

建议将 Nginx 四层代理作为统一入口方案的一部分,配合七层代理,构建更完整、更灵活的服务网关。

作者头像

刘宇帅

非著名程序员,全栈开发工程师,长期专注系统开发与架构设计。

提示

功能待开通!


暂无评论~

相关文章

浏览器报错 net::ERR_INCOMPLETE_CHUNKED_ENCODING

nginx服务器返回200但是浏览器报错 net::ERR_INCOMPLETE_CHUNKED_ENCODING 原因是nginx在获得后端服务器返回数据时,数据过大需要存在临时文件中,但是当前运行nginx用户,没有该文件的读写权限 导致的。 如何证实 可以查看nginx的日志,会有以下类似错误 2018/03/22 16:11:35 [crit] 9519#0: *339625 open() "/var/lib/nginx/tmp/fastcgi/5/02/0000000025" failed 很明显,nginx无法写/var/lib/nginx/tmp/fastcgi/5/02/000

Nginx 路由匹配

模式 含义 location = /uri = 表示精确匹配只有完全相等才会匹配成功 location ^~ /uri ^~ 表示对路由进行前缀匹配 location ~ /uri ~ 表示对路由进行正则匹配 location ~* /uri ~* 表示对路由进行不区分大小写的正则匹配 location /uri 不带任何修饰符也表示前缀匹配 location / 默认匹配,任何没有匹配到的uri 多个 location 配置的情况下匹配顺序为(匹配到某一等级就结束,同一规则时匹配长度长的优先): 首先精确匹配 = 其次前缀匹配 ^~ 其次是按文件中顺

Nginx日志配置推荐

推荐日志配置 log_format main 'remote_addr=[$remote_addr] http_x_forward=[$http_x_forwarded_for] time=[$time_local] request=[$request] ' 'status=[$status] byte=[$bytes_sent] elapsed=[$request_time] upstream_connect_time=[$upstream_connect_time] upstream_response_time=[$upstream_response_time] '

Nginx 反向代理常见问题汇总与解决方案

在使用 Nginx 做反向代理时,经常会遇到一些看似莫名其妙的问题,比如返回 502 错误、路径出错、真实 IP 丢失等等。本文总结了开发和部署中最常见的 Nginx 反向代理问题,并给出对应的排查和解决方案,帮助你快速定位和修复问题。 目录 一、502 Bad Gateway 二、路径拼接异常 三、获取不到真实客户端-IP 四、跨域请求失败 五、WebSocket 无法正常工作 六、请求体过大导致-413-错误 七、反向代理跳转失效 八、HTTPS-代理配置问题 九、文件下载异常或中断 十、缓存未生效或生效异常 总结 一、502 Bad Gateway 这个错误意味着 Nginx 无法成

Nginx 四层最佳配置

stream { log_format proxy 'time=[$time_local] remote_addr=[$remote_addr]' ' protocol=[$protocol] status=[$status] byte_send=[$bytes_sent] byte_received=[$bytes_received] ' 'session_time=[$session_time] upstream_addr=[$upstream_addr] ' 'upstream_