Nginx配置端口转发 映射 以及连接超时问题

本文详细解析了端口映射与端口转发的区别,通过实例演示如何使用Nginx进行端口映射,包括http和tcp/udp类型的配置,并深入探讨了Nginx配置参数的优化及监控。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

				版权声明:本文为博主原创文章,未经博主允许不得转载。					https://blog.youkuaiyun.com/qq_31226223/article/details/78766314				</div>
							            <div id="content_views" class="markdown_views">
						<!-- flowchart 箭头图标 勿删 -->
						<svg xmlns="http://www.w3.org/2000/svg" style="display: none;"><path stroke-linecap="round" d="M5,0 0,2.5 5,5z" id="raphael-marker-block" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></path></svg>
						<h3 id="说到端口转发就不得不提端口映射这两个的概念比较容易混淆喜欢较真的同学就去查查概念吧"><a name="t0"></a>说到端口转发,就不得不提端口映射,这两个的概念比较容易混淆。喜欢较真的同学就去查查概念吧……</h3>

知乎有人说:

端口转发:你给我了,我打开看看,发现这上面标志显示是要给张三,那么我就给张三去。如果标志是给李四,那我就再给李四去。

端口映射:你放到我左手,我就直接给张三;你放到我右手,我就直接给李四。这中间我不管你放我手上的是什么东西。

这里我认为应该叫端口映射为好,但是不管是什么都是用了nginx的反向代理模块。

先看图和业务吧

这里写图片描述

上面这个图呢,假设我们这五台服务器在一个集群里面,但是呢,由于集群内防火墙的原因,你的电脑只能连接1号机器,2、3、4、5访问不了,这个时候我们就需要在1号机器做做文章。通过访问1号机器的不同端口,来间接地访问后面的其他机器。

假设五台机器的IP分别是192.168.1.10、192.168.1.20、192.168.1.30、192.168.1.40、192.168.1.50

OK!那我们直接自定义端口映射配置下Nginx就好了呗?

No No No!我们再具体一下我们的需求。

我们把连接类型划分一下:两种。

第一种:http(对应Nginx http模块)

第二种:tcp/udp(对应Nginx stream模块)

比如我们的web项目,需要用浏览器访问的或其他的基于http协议的,要配置在http模块下。

像SSH,FTP这些,需要配置在stream模块下。

先说http,比如我们2号机器上有一只汤姆猫,端口8080,这时候我们就需要在Nginx上添加如下配置:

http{
    proxy_read_timeout 300s;
    proxy_send_timeout 300s;
    keepalive_requests 1000;
    keepalive_timeout 300s;
    server{
        listen  8888;
        location / {
            proxy_pass http://192.168.1.20:8080;
        }
    }
}
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

这段代码的意思就是,指向我1号机器(192.168.1.10:8888)的连接,都映射到192.168.1.20:8080上面。

参数:

“proxy_read_timeout”:从代理服务器读取响应的超时时间(默认60s),这个可以解决因为代理服务器响应过慢而导致的504 Time-out
“proxy_send_timeout”:向代理服务器发送请求的超时时间(默认60s)
“keepalive_timeout”:设置一个保持活动的客户端连接在服务器端保持打开状态的超时时间(默认75s)
“keepalive_requests”:这个参数默认是100,意思就是,一个连接,在他保持连接的状态内(我们设置的是300s),最多能发送1000个请求,如果超过1000请求,那么nginx会把这个连接断掉

如果我们3、4、5机器上面有数据库或者需要SSH连接的话,就要使用stream模块。

Demo如下:

stream{
    proxy_timeout 30m;
    server{
        listen  1521;
        proxy_pass 192.168.1.30:1521;
    }
    server{
        listen  3306;
        proxy_pass 192.168.1.30:3306;
    }
    server{
        listen  4022;
        proxy_pass 192.168.1.40:22;
    }
    server{
        listen  5022;
        proxy_pass 192.168.1.50:22;
    }
}
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

需要访问什么,加上我们自定义的端口号,就大功告成。比如我们要访问3号机器的MySQL,那么我们数据库连接就配置192.168.1.10:3306这样我们就能通过Nginx来轻松访问到192.168.1.30:3306的数据库了。

这里留意一个参数–”proxy_timeout 30m;“

注意:“proxy_timeout”这个参数可以写在stream节点下,所有server都生效,也可以单独写在一个server的节点下

这个参数不写的话,默认连接超时是10min,比如我们使用filezilla,10分钟没有任何动作的话,你的连接就会被干掉,ssh、数据库也是的。这里我保守设置30min,具体看自己的需求。

注意,这个超时并不会影响传输中的数据,比如我们设置成10s,这时候我们从ftp服务器上面下载一个文件,10s没下载完,且你没有任何动作的话,会提示连接已断开,但是实测文件还能继续传输,这应该是传输文件是单独出来的一个连接的缘故。

最后多说一点Nginx的配置。

worker_processes  2;

events{
    worker_connections  1024;
}

 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

这是Nginx必须的配置,第一个参数,作者推荐写成处理器逻辑核心的个数,实际带来的最直观的效果就是,启动Nginx之后,一个主进程,外加这个参数的个数进程。比如我服务器32逻辑核心,我写了32。启动之后,33个nginx.exe,你闹不闹心,反正我是很闹心。我自己做过压力测试,3000+并发,这个参数写2都没任何问题。所以我推荐写2或者4即可。

第二个参数是最大连接数,这个就看具体使用环境了。几千几万都可以。

(补充:Windows下worker_processes写多少都只有一个worker在工作,且一个worker只能承受1024连接数,这个官方已经说明,而且我亲自实验了,这是操作系统层面的原因。还有一个点[Linux]就是每个worker能够处理的连接数和ulimit里面的‘open files’参数有关系,大致为“全局最大连接数 = worker数量 * open files 参数”)

最后,我们使用它很方便,最好还能监控。

OK!使用ngx_http_stub_status_module

具体的配置写在http模块下

server{
        location /basic_status {
            stub_status;
        }
    }
 
  • 1
  • 2
  • 3
  • 4
  • 5

这时候我们访问http://192.168.1.10/basic_status,我们就能看到效果了。 文本如下:

Active connections: 22
server accepts handled requests
453 453 67
Reading: 0 Writing: 1 Waiting: 0

第一个就是当前活动的连接数

下面的三个数值分别是 处理连接数/创建握手数/处理请求数

———————————————————————

嗯……文章中有什么不对或者不妥的地方欢迎提出来
【LOG】
2017.12.28 更新: http/stream节点参数
2018.01.06 更新: 补充说明worker_processes参数和worker_connections参数
<think>好的,我现在需要帮助用户解决关于NGINX转发TCP流量时如何配置域名转发问题。首先,我需要回想一下用户的历史提问,之前他问过如何检查Nginx配置是否合法,现在转向了TCP流量的域名转发配置。这可能意味着用户正在搭建一个需要处理TCP协议的服务,比如数据库、邮件服务器或者自定义的TCP应用,希望通过Nginx作为反向代理来实现负载均衡或SSL终止等。 首先,我需要确认Nginx的版本是否支持TCP转发。因为Nginx默认只支持HTTP反向代理,TCP和UDP的转发需要Stream模块,这个模块在Nginx 1.9.0及以上版本才有。所以用户可能需要先确认自己的Nginx版本,并确保编译时包含--with-stream选项。如果用户使用的是预编译的包,比如Ubuntu的nginx-extras,可能已经包含了这个模块,但需要检查配置是否加载了stream模块。 接下来,用户的需求是配置域名转发。在HTTP中,可以通过server_name来指定域名,但在TCP转发中,传统的server_name并不适用。这时候可能需要使用SNI(Server Name Indication)来区分不同的域名,但SNI主要用于TLS握手,而普通的TCP流量可能不包含这种信息。因此,用户可能需要在Nginx中通过不同的端口来区分不同的服务,或者如果流量是TLS加密的,可以利用SNI来分离。 所以,我需要分步骤思考如何配置: 1. 确保Nginx安装并启用了Stream模块。 2. 编辑nginx.conf,在stream块中配置upstream和server。 3. 配置多个域名可能需要不同的端口,或者使用SNI(如果流量是TLS的)。 4. 测试配置并重载Nginx。 另外,用户可能还关心SSL终止的情况,比如是否需要配置SSL证书在Nginx上,或者直接透传到后端服务器。如果是前者,需要在stream块中配置SSL证书和密钥,并启用ssl_preread来获取SNI信息,然后根据SNI来路由到不同的后端。 可能的问题点包括:用户是否了解stream模块的配置语法,如何处理多个域名对应不同的后端服务,是否需要SSL配置,以及如何测试配置是否正确。 同时,我需要考虑到用户可能的误区,比如认为TCP转发可以像HTTP一样通过域名直接区分,但实际上在TCP层没有Host头,所以需要依赖端口或SNI。因此,用户可能需要为每个域名分配不同的端口,或者使用TLS和SNI来实现基于域名的转发。 最后,我需要给出具体的配置示例,说明每个部分的作用,并提醒用户检查配置的正确性,使用nginx -t测试,并重载服务。可能还需要提到日志查看和常见错误的解决方法,比如端口冲突、权限问题等。</think>--- ### **NGINX转发TCP流量及域名配置指南** Nginx的 **`stream` 模块**支持TCP/UDP流量的代理和负载均衡。以下是基于域名(或SNI)转发TCP流量的详细配置方法: --- #### **1. 前置条件** - **Nginx版本 ≥ 1.9.0**,需启用 `stream` 模块(编译时需加 `--with-stream`)。 - **检查模块是否启用**: ```bash nginx -V 2>&1 | grep -o with-stream # 输出 with-stream 表示已启用 ``` 若未启用,需重新编译或安装包含stream模块的包(如Ubuntu的 `nginx-extras`)。 --- #### **2. 基础配置:单端口转发** 在 `nginx.conf` 的 **`stream` 块**中定义TCP代理规则: ```nginx stream { # 定义上游服务器组 upstream backend_tcp { server 192.168.1.100:3306; # 后端MySQL服务器 } # 监听TCP端口转发 server { listen 3306; # 监听本机3306端口 proxy_pass backend_tcp; # 转发到上游组 proxy_connect_timeout 5s; # 连接超时时间 } } ``` --- #### **3. 基于域名的多端口转发(非TLS场景)** **原理**:TCP层无域名概念,需通过**不同端口**区分服务。 **示例**:将 `domain1.com:1234` 和 `domain2.com:5678` 转发到不同后端: ```nginx stream { upstream backend1 { server 10.0.0.10:3306; # 对应domain1的数据库 } upstream backend2 { server 10.0.0.20:6379; # 对应domain2的Redis } server { listen 1234; proxy_pass backend1; } server { listen 5678; proxy_pass backend2; } } ``` **客户端连接方式**: ```bash mysql -h domain1.com -P 1234 # 访问backend1 redis-cli -h domain2.com -p 5678 # 访问backend2 ``` --- #### **4. 基于SNI的域名转发(TLS加密场景)** **适用场景**:TCP流量为TLS加密(如MySQL SSL连接),需通过 **SNI(Server Name Indication)** 提取域名。 **配置步骤**: 1. **启用SNI解析**: ```nginx stream { # 映射域名到上游组 map $ssl_preread_server_name $backend { domain1.com backend_ssl1; domain2.com backend_ssl2; default backend_default; } # 定义上游组 upstream backend_ssl1 { server 192.168.1.101:3306; } upstream backend_ssl2 { server 192.168.1.102:3306; } # 监听统一端口,依赖SNI分流 server { listen 3306; proxy_pass $backend; # 根据SNI动态选择上游 ssl_preread on; # 启用SNI解析 proxy_ssl on; # 若后端也需TLS,开启此选项 proxy_ssl_name $backend; # 传递SNI到后端 } } ``` 2. **客户端连接**(需指定SNI): ```bash mysql --ssl-mode=REQUIRED -h domain1.com -P 3306 ``` --- #### **5. 高级配置:SSL终止与透传** - **SSL终止(解密在Nginx)**: 在Nginx配置证书,解密后明文转发到后端: ```nginx server { listen 3306 ssl; ssl_certificate /path/to/cert.pem; ssl_certificate_key /path/to/key.pem; proxy_pass backend_tcp; } ``` - **SSL透传(后端处理加密)**: 仅转发TCP流,不干预加密: ```nginx server { listen 3306; proxy_pass backend_tcp; } ``` --- ### **关键注意事项** 1. **端口冲突**: 确保监听端口未被其他进程占用(检查工具:`lsof -i :端口号`)。 2. **防火墙规则**: 开放Nginx监听端口(如3306): ```bash sudo ufw allow 3306/tcp ``` 3. **日志调试**: 在 `stream` 块中启用日志: ```nginx log_format tcp_proxy '$remote_addr [$time_local] $protocol $status'; access_log /var/log/nginx/tcp-access.log tcp_proxy; ``` 4. **性能优化**: - 调整 `worker_processes` 和 `worker_connections`。 - 使用 `proxy_buffer_size` 控制缓冲区大小。 --- ### **验证与维护** 1. **测试配置合法性**: ```bash sudo nginx -t # 检查语法 ``` 2. **重载配置**: ```bash sudo systemctl reload nginx ``` 3. **实时监控连接**: ```bash sudo ss -tulnp | grep nginx # 查看监听端口 sudo ngrep -d any port 3306 # 抓取流量(调试用) ``` --- ### **典型应用场景** | **场景** | **配置要点** | |-------------------------|------------------------------------------| | 数据库代理(MySQL/Redis)| 使用 `stream` + SNI分流,开启SSL加密 | | 游戏服务器代理 | 高并发优化,调整 `proxy_timeout` | | 自定义TCP协议转发 | 透传模式,避免Nginx解析协议内容 | 通过上述配置Nginx可实现灵活的TCP流量转发,适用于需高可用、负载均衡或统一入口的TCP服务架构。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值