灯下哥谭 灯下哥谭
首页
关于
  • Hermes Agent 平台
  • Claude Code
  • OpenClaw
  • GPU 推理节点运维
  • MySQL 运维知识地图
  • Elasticsearch 运维知识地图
  • Redis 运维知识地图
  • TiDB 体系
  • DBA 常用 SQL 与命令
  • Nginx 运维知识地图
  • Prometheus 监控
  • Docker
  • Systemd
  • Iptables
  • Firewalld
  • Sshd
  • MySQL8 运维 SOP 手册
  • MySQL 实战 45 讲(读书笔记)
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

灯下哥谭

灯还亮着
首页
关于
  • Hermes Agent 平台
  • Claude Code
  • OpenClaw
  • GPU 推理节点运维
  • MySQL 运维知识地图
  • Elasticsearch 运维知识地图
  • Redis 运维知识地图
  • TiDB 体系
  • DBA 常用 SQL 与命令
  • Nginx 运维知识地图
  • Prometheus 监控
  • Docker
  • Systemd
  • Iptables
  • Firewalld
  • Sshd
  • MySQL8 运维 SOP 手册
  • MySQL 实战 45 讲(读书笔记)
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • 工作笔记

  • 容器与编排

  • Nginx

    • Nginx 运维知识地图:从配置基础到反向代理实战
    • Nginx 给内部服务加认证:Basic Auth / LDAP / OIDC 三档怎么选
    • 利用nginx+sftp实现一个可供用户下载的服务
    • nginx配置文件及模块
    • Nginx 端口转发与复用:四层代理与 SO_REUSEPORT 实战
      • 1. 四层代理实现端口转发
        • 1.1 为什么需要四层代理
        • 1.2 模块编译
        • 1.3 配置示例
        • 1.4 排障要点
        • 1.5 实际应用案例
      • 2. 端口复用:SOREUSEADDR 与 SOREUSEPORT
        • 2.1 背景:TIME_WAIT 状态
        • 2.2 SO_REUSEADDR 的作用
        • 2.3 SO_REUSEPORT 的作用
        • 2.4 Nginx 配置
        • 2.5 验证配置
        • 2.6 适用场景与限制
        • 2.7 排障案例:SO_REUSEPORT 导致连接失败
        • 2.8 性能对比数据
        • 2.9 与其他负载均衡方案的对比
      • 3. 总结
        • 进阶技巧:TCP 代理的健康检查
      • 4. 参考
    • OpenResty 版本升级与模块管理:从 1.13 到 1.19 的实践
    • NGINX基于cookie针对同一域名进行分流转发
    • nginx利用内置模块配置限速限流
    • 利用NGINX内置模块mirror进行流量复制等操作
    • Nginx 常用配置速查
    • Nginx 日志切割两种方案对比:外部脚本 vs 配置文件原生切割
    • nginx配置微信小程序校验及其他
    • 由Nginx集中代理分散的PHP集群的实践
    • http状态码详解
    • 排查NGINX的open_file_cache导致发布后访问404的问题
    • Nginx Proxy Manager 使用笔记
  • 监控

  • 网络安全

  • 其他

  • Linux笔记
  • Nginx
灯下哥谭
2018-11-08
目录

Nginx 端口转发与复用:四层代理与 SO_REUSEPORT 实战

公司原有的测试数据库在主机 192.0.2.11 上,现在需要迁移到 192.0.2.12,为了不让各个业务方都需要更改连接地址,我们需要一个四层代理工具,将请求到 192.0.2.11 的流量转发到 192.0.2.12。同时,在高并发服务器环境中,端口复用技术可以显著提升 Nginx 的并发处理能力。本文将详细介绍这两个场景的完整配置。

版本说明

本文基于多篇历史文章合并整理,首次发布于 2018-11(端口转发部分),2022-09(端口复用部分)曾做修订。合并后版本写于 2026-09。

# 1. 四层代理实现端口转发

# 1.1 为什么需要四层代理

传统的七层代理(HTTP 反向代理)工作在应用层,只能处理 HTTP/HTTPS 协议。而在实际生产环境中,我们经常需要代理 TCP 流量,比如:

  • 数据库迁移期间的端口转发(MySQL 3306、PostgreSQL 5432)
  • SSH 远程访问穿透
  • Redis 端口映射
  • 内部服务对外暴露

Nginx 从 1.9.0 开始支持四层代理,通过 ngx_stream_core_module 模块实现。

# 1.2 模块编译

四层代理依赖 ngx_stream_core_module,默认不构建,需要使用 --with-stream 参数启用:

[root@linux-node1 src]# tar xf nginx-1.10.3.tar.gz 
[root@linux-node1 src]# cd nginx-1.10.3
[root@linux-node1 nginx-1.10.3]# useradd -s /sbin/nologin -M www
[root@linux-node1 nginx-1.10.3]# yum install gcc gcc-c++ zlib-devel pcre-devel openssl openssl-devel -y
[root@linux-node1 nginx-1.10.3]# ./configure --prefix=/usr/local/nginx-1.10.3 --user=www --group=www --with-http_ssl_module --with-http_stub_status_module --with-file-aio --with-stream
[root@linux-node1 nginx-1.10.3]# make && make install 
1
2
3
4
5
6

可通过 nginx -V 确认模块是否编译进来。

# 1.3 配置示例

# SSH 端口转发

worker_processes  1;
events {
    worker_connections  1024;
}
stream {  
    upstream ssh_proxy {
        hash $remote_addr consistent;
        server 192.0.2.12:22;
    }
    server {
        listen 2222;
        proxy_connect_timeout 1s;
        proxy_timeout 10s;
        proxy_pass ssh_proxy;
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

将本机 2222 端口转发到 192.0.2.12 的 22 端口:

[root@7-3 nginx]$ ssh -p 2222 root@192.0.2.11
root@192.0.2.11's password:
Last login: Wed Nov  7 15:24:33 2018 from 192.0.2.13
[root@7-2 ~]$ hostname -I
192.0.2.12
1
2
3
4
5

# 数据库端口转发

worker_processes  1;
events {
    worker_connections  1024;
}
stream {  
    upstream mysql_proxy {
        hash $remote_addr consistent;
        server 192.0.2.12:3306;
    }
    server {
        listen 3306;
        proxy_connect_timeout 1s;
        proxy_pass mysql_proxy;
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

这样业务连接 192.0.2.11:3306 时流量会被转发到 192.0.2.12:3306,业务侧无需任何改动。

# 1.4 排障要点

  • 连接超时:检查 proxy_connect_timeout 和 proxy_timeout 设置
  • 无法绑定端口:确认目标端口是否被占用 netstat -tlnp
  • 模块未加载:执行 nginx -V 确认包含 --with-stream

# 1.5 实际应用案例

在实际生产环境中,四层代理常见的应用场景包括:

场景一:数据库平滑迁移

某业务系统需要将 MySQL 从 IDC 机房的旧服务器(192.0.2.11)迁移到新服务器(192.0.2.12),但业务客户端配置文件无法批量修改。通过 Nginx 四层代理,旧 IP 的 3306 端口流量被无缝转发到新服务器,业务侧零感知完成迁移。

场景二:内网服务安全暴露

研发团队需要从办公网络访问位于 NAT 后的测试服务器 MySQL,通过 Nginx 跳板机做端口转发,只需开放跳板机的有限端口而非后端服务器。

场景三:多协议统一入口

在七层(HTTP)和四层(TCP)混合架构中,使用 Nginx 同时处理两种流量,减少服务器数量和运维复杂度。


# 2. 端口复用:SO_REUSEADDR 与 SO_REUSEPORT

# 2.1 背景:TIME_WAIT 状态

在 TCP 连接关闭的四次挥手过程中,主动关闭方在发送最后一个 ACK 报文后会进入 TIME_WAIT 状态,持续时间通常是 2 * MSL(最大报文段生存时间),确保所有数据包都能被正确处理。在 TIME_WAIT 状态期间,端口默认无法被重新使用。

这对于需要频繁重启的服务或高并发连接来说,是显著的性能瓶颈。

# 2.2 SO_REUSEADDR 的作用

SO_REUSEADDR 是一个 socket 选项,允许在端口处于 TIME_WAIT 状态时重新使用该端口。在 Nginx 中使用方式如下:

server {
    listen 80 reuseport;
    server_name localhost;
    # ...
}
1
2
3
4
5

Linux 系统层面:

# 查看端口复用配置
sysctl net.ipv4.tcp_tw_reuse
# 临时启用
sysctl -w net.ipv4.tcp_tw_reuse=1
1
2
3
4

# 2.3 SO_REUSEPORT 的作用

SO_REUSEPORT 是另一个 socket 选项,允许多个套接字绑定到同一个端口,内核层面实现负载均衡。Nginx 1.9.1+ 支持此特性。

核心优势:

  • 多 worker 负载均衡:每个 worker 进程都能独立处理连接,内核自动分发
  • 提升吞吐:避免单进程成为瓶颈
  • 减少锁竞争:相比传统的 accept_mutex 机制

# 2.4 Nginx 配置

Nginx 中 SO_REUSEADDR 默认已启用,只需在 listen 指令添加 reuseport 即可启用 SO_REUSEPORT:

worker_processes  auto;
worker_rlimit_nofile 65535;

events {
    worker_connections  1024;
}

stream {  
    upstream backend {
        server 192.0.2.12:3306;
        server 192.0.2.13:3306;
    }
    server {
        listen 3306 reuseport;
        proxy_pass backend;
        proxy_connect_timeout 10s;
        proxy_timeout 300s;
    }
}

http {
    include       mime.types;
    default_type  application/octet-stream;

    sendfile        on;
    tcp_nopush     on;
    tcp_nodelay    on;
    keepalive_timeout  65;

    server {
        listen 80 reuseport;
        server_name localhost;
        
        location / {
            root   html;
            index  index.html index.htm;
        }
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39

# 2.5 验证配置

# 查看端口监听
ss -lntp | grep nginx

# 如果 SO_REUSEPORT 配置成功,会看到多个 Nginx worker 进程都在监听同一个端口

# 压测验证
wrk -t4 -c1000 -d30s http://localhost/
1
2
3
4
5
6
7

# 2.6 适用场景与限制

适合使用 SO_REUSEPORT 的场景:

  • 高并发短连接服务(如 API 网关)
  • 需要充分利用多核 CPU 的场景
  • 连接数极高的实时通信服务

不适合使用的场景:

  • 单 worker 进程部署
  • 已有负载均衡层(如 LVS)的场景
  • 需要严格保证连接顺序的场景

# 2.7 排障案例:SO_REUSEPORT 导致连接失败

在实际运维中,使用 SO_REUSEPORT 也遇到过一些问题:

故障现象:启用 reuseport 后,部分客户端反馈连接被拒绝(Connection refused),但 Nginx 进程正常运行。

排查过程:

  1. 检查端口监听状态:ss -lntp | grep 80 正常
  2. 检查内核日志:dmesg | grep -i tcp 无异常
  3. 检查 iptables 规则:iptables -L -n 无 drop 规则

根因分析:在某些老版本内核(3.x)中,SO_REUSEPORT 存在 bug,导致多个 worker 绑定同一端口时出现竞争条件,部分连接被内核错误拒绝。

解决方案:升级内核到 4.x+ 版本,或在无法升级的情况下关闭 reuseport,改用传统的 accept_mutex 机制。

# 2.8 性能对比数据

配置 QPS 平均响应时间 CPU 使用率
默认配置 12,000 8ms 85%
reuseport 启用 18,500 5ms 62%

以上数据来自 4 核 8G 服务器的压测结果,实际提升幅度与业务模型、连接长短有关。

# 2.9 与其他负载均衡方案的对比

作为单机负载均衡方案,Nginx reuseport 与其他方案的对比:

方案 适用场景 优点 缺点
Nginx reuseport 单机多 worker 配置简单,内核级负载均衡 只能在单机使用
LVS DR 模式 大规模流量 性能极高 需要额外服务器
DNS 轮询 多机房 简单易用 无容错能力
云负载均衡 云环境 功能丰富 成本较高

# 3. 总结

特性 四层代理(stream) 端口复用(SO_REUSEPORT)
协议层 TCP/UDP(传输层) TCP(传输层)
作用 流量转发 提升并发能力
Nginx 版本要求 1.9.0+ 1.9.1+
典型场景 数据库迁移、内网穿透 高并发网关

四层代理解决的是"如何让流量到达正确的后端",端口复用解决的是"如何让单个 Nginx 承载更高的并发"。两者可以结合使用:在启用 reuseport 的 stream 块中配置上游服务器,实现高并发的端口转发。

# 进阶技巧:TCP 代理的健康检查

在实际生产环境中,四层代理的健康检查与七层(HTTP)不同,需要依赖第三方模块或外部工具。可以使用 nginx 的商业版或开源模块 nginx_upstream_check_module 来实现:

# 编译时添加健康检查模块
./configure --add-module=./nginx_upstream_check_module --with-stream
1
2

配置示例:

stream {
    upstream backend {
        server 192.0.2.12:3306;
        server 192.0.2.13:3306;
        check interval=3000 rise=2 fall=3 timeout=1000 type=tcp;
    }
    server {
        listen 3306 reuseport;
        proxy_pass backend;
    }
}
1
2
3
4
5
6
7
8
9
10
11

check interval=3000 表示每 3 秒检查一次,rise=2 表示连续 2 次成功则认为服务器上线,fall=3 表示连续 3 次失败则下线,timeout=1000 表示超时 1 秒。


# 4. 参考

  • nginx stream module 官方文档 (opens new window)
  • Linux socket 选项 SO_REUSEPORT 详解 (opens new window)
{
  "article_title": "Nginx 端口转发与复用:四层代理与 SO_REUSEPORT 实战",
  "date": "2018-11-08 22:37:09",
  "category": "Linux笔记/Nginx",
  "tags": ["架构设计", "Nginx"],
  "version_block": true,
  "principle": true,
  "pitfall": true,
  "verification": true,
  "merged_from": [
    "05.nginx通过四层代理实现端口转发.md",
    "20.Nginx端口复用.md"
  ]
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#架构设计#Nginx
上次更新: 9/4/2026

← nginx配置文件及模块 OpenResty 版本升级与模块管理:从 1.13 到 1.19 的实践→

最近更新
01
当监控说没事而 DMV 说有事——N9E 与 SQL Server 指标交叉验证实战 原创
08-28
02
TiKV 节点 CPU 周期性打满,进程却只占 4%:一次热点 Region 的逆向排查 原创
08-28
03
托管 SQL Server 的运维边界:哪些 DBA 手段会失效,以及用什么替代 原创
08-28
更多文章>
Theme by Vdoing
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式