“因为TCP端口号是16位无符号整数,最大65535
,所以一台服务器最多支持65536
个TCP socket连接.” 这是一个非常经典的误解! 即使是有多年网络编程经验的人,也会持有这个错误结论。
其中0-1023 端口是系统保留的端口,并不能被普通应用程序所使用,这里暂时不考虑这个情况.而是以65535 代替。
要戳破这个错误结论,可以从理论和实践两方面来。
理论
*unix
系统通过一个四元组来唯一标识一条TCP连接. 这个四元组的结构是{local_ip, local_port, remote_ip, remote_port}。所以,对于IPv4, 系统理论上最多可以管理2^(32+16+32+16)
,也就是2的96次方个连接。
IPv4 可以理解成一个 32位正数
- 因为对于同一台服务器来说,一般只有一个
local_ip
,那么同一台服务器可以管理 2^(16+32+16) 个连接。 - 一个服务(进程, 如 Nginx 进程)一般只监听一个
local_port
,那么同一台服务就可以管理 2^(32+16) 个连接。 - 如果从一台远端机器(所谓的 client)来连接这台服务器上的一个服务,那么
local_ip
,local_port
,remote_ip
这3个变量是固定的,那么就只能建立 2^16=65536 个连接了。这就是经典的误解的来源!
如果不仅仅考虑TCP,则是一个五元组,加上协议号(TCP,UDP或者其它)。所以一个服务器最多能支持多少个TCP连接,它的限制不在于四元组,而是其他参数。
文件描述符
我们知道在Linux中一切都是文件(socket也是文件),最大能打开的文件数量,决定了能够同时建立TCP连接的数量,那么一台服务器最大能打开多少个文件呢?
- 查看系统支持的最大打开文件描述符数,
|
|
- 单个进程能打开的最大文件描述符数量
|
|
这两个值都是可以改变的,一般在进行压力测试的时候,会手动调整这个值。
ip_local_port_range
如果某个客户端向同一个TCP端点(ip:port)发起主动连接,那么每一条连接都必须使用不同的本地TCP端点,如果客户端只有一个IP则是使用不同的本地端口,该端口的范围在*nix
系统上的一个例子是32768到61000左右,可以通过如下命令查看:
|
|
也就是说,一个客户端连接同一个服务器的同一个ip:port(比如进行压力测试),最多可以发起30000个左右的连接。不过,对于client端,操作系统会自动根据不同的远端 ip:port,决定是否重用本地端口。
内存&CPU
一个ESTABLISH
状态的socket
大约消耗3.3KB
内存,如果没有数据业务的话CPU占用很低。所以从内存角度来看,一台服务器能支持的最大TCP 连接数量也是有上线的,远远到不了4元组的上限。
总结
一台服务器最大能支持多少条 TCP 连接的上限是确定的,那就是2^96
个,但是它的下限,需要根据很多情况来判断,比如内存、CPU、文件描述符等。没有具体答案。