背景
近期配合开发同事排查线上压测问题时,碰到很常见的主机临时端口被TCP time_wait占满的问题,于是讨论到服务端会不会也有可能出现类似问题。
网络上查了一些资料大部分都说是没有端口限制的,当然这和我们在服务端用ss或者netstat命令查看端口连接的情况是一致的。
但是chatgpt给了不太一样的回答:当使用TCP时,服务端使用一个固定的端口来监听客户端的连接请求。当客户端请求连接时,服务端会接受连接请求,并为该连接分配一个唯一的临时端口。
验证
为了搞清楚这个问题,搭了个小的环境自己验证一下,如下图
- 服务端(192.168.72.200)通过nginx监听80端口提供web服务
- 人为将服务端临时端口范围改到65531-65535,也就是说只有5个可用的临时端口
- 客户端(192.168.72.201和192.168.72.211)通过模拟多个TCP连接来连接服务端
# 模拟创建多个从客户端到服务端80端口的TCP连接
exec 3<>/dev/tcp/192.168.72.200/80
exec 4<>/dev/tcp/192.168.72.200/80
exec 5<>/dev/tcp/192.168.72.200/80
exec 6<>/dev/tcp/192.168.72.200/80
exec 7<>/dev/tcp/192.168.72.200/80
exec 8<>/dev/tcp/192.168.72.200/80
exec 9<>/dev/tcp/192.168.72.200/80
图中可以看到有包括TIME_WAIT和ESTABLISHED状态的TCP连接共13个,均是从客户端连到服务端,也就是说服务端在80端口提供对服务并没有受到系统临时端口范围的限制。
- 接着在服务端(192.168.72.200)上主动发起到另一台服务器(192.168.72.201)上6443端口的TCP连接
exec 4<>/dev/tcp/192.168.72.201/6443
exec 5<>/dev/tcp/192.168.72.201/6443
exec 6<>/dev/tcp/192.168.72.201/6443
exec 7<>/dev/tcp/192.168.72.201/6443
exec 8<>/dev/tcp/192.168.72.201/6443
exec 9<>/dev/tcp/192.168.72.201/6443
图中可以看到,当创建到第6个TCP连接时系统报错“无法指定被请求的地址”,也就是说没有多的端口可以用了。从图上面的netstat信息也可以清晰看出来,现有对外发起的TCP连接已经把本地的65531-65535这5个端口都占用了,按照ip_local_port_range的限制,没有多的端口可用,所以报错。
结论
服务端在监听端口上提供TCP服务时,和多个客户端建立的连接并不受系统ip_local_port_range中端口的限制;
而在作为客户端时,对外发起TCP连接需要使用本地1024以上的临时端口与对端建立连接,这时候是要受到系统ip_local_port_range中端口限制的。
疑问
最后,有可能chatgpt的回答也并不是错的,会不会是服务端这一侧TCP监听端口和内部的临时端口池有着某种映射关系,而这个映射的临时端口池是不受系统中ip_local_port_range限制的?有没有大佬能解惑下...