一台Linux机器上最多能建立多少个TCP连接?

Posted 狱典司

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了一台Linux机器上最多能建立多少个TCP连接?相关的知识,希望对你有一定的参考价值。

一台Linux机器上最多能建立多少个TCP连接?

看面经看到有的公司面试会问这个问题,上网搜了搜感觉没有找到特别全面且易懂的答案,遂思考后总结如下,如有纰漏还请指出!

受限制的因素:

  1. 计算机(或虚拟机)能够打开的最大文件个数 file-max,受硬件配置影响;

在通信的每一方(Linux OS)上,每个socket其实都属于一个打开的文件,通过文件描述符fd作为句柄去操作,该限制可以用ulimit -a查看,也可以用cat /proc/sys/fs/file-max查看,open file标识了当前用户下进程默认最多能打开的文件描述符个数,缺省为1024。


可以通过修改配置文件的方式修改该上限值:sudo vi /etc/security/limits.conf
在文件尾部写入以下配置,soft 软限制,hard 硬限制。如下所示:

soft nofile 65536		#这里将软限制改为65536,简单的匹配0~65535端口号per Port per Connnection的情况。
hard nofile 100000

说到这里有不得不涉及进程的因素:
在linux上进行网络编程,若需要打开一个文件并获取其文件描述符,必然基于一个进程,进程的地址空间内部存有打开文件描述符列表,简称fd列表,那么我们的机器上有几个个关于进程的参数是matter的:

  • 系统分配给一个进程的空间是多大
  • 一个进程最多能打开多少个fd
  • 系统最多能用多少个进程

因为进程的启用会分配除了fd列表之外的其他资源,这些资源都会占用cpu和内存,按照这样的逻辑,在一台Linux机器上最多能建立多少个TCP连接?的命题下,进程越少,每个进程能打开的文件描述符越多越好,因为这样资源的有效率更高。

有的同学也可能想过用线程去开fd,但是需要注意的是,即使线程在其独立的执行栈中使用open()打开了某个文件,并用int变量去接收了操作句柄,这并不代表其他线程就不能调用到这个fd了,因为最终fd是放置在同一进程的fd列表上的,线程栈内部私有的只是一个变量,并不是fd的绝对控制权。我们也知道开启线程也需要为线程分配独立的执行栈,那么用线程去打开fd反而会额外占用更多的“无效资源”。

  1. 最大端口数ip_local_port_range

TCP数据包中用于表述端口的字段是16位,最多可以表示2^16也就是65535个端口;

使用sysctl net.ipv4.ip_local_port_rangecat /proc/sys/net/ipv4/ip_local_port_range,一般情形下:linux临时端口号范围是(32768,61000)

  1. ip数量

ip(ipv4)数量的理论最大值,受限于ip的位数 ---- ip长度为32位,那么极限最优条件下(但没有这个可能)单机可以拥有2^32个ip地址,但这样就把世界上所有的ip都用光了。

每个TCP连接由唯一的TCP四元组可以唯一确定,即:(local IP, local Port, remote IP, remote Port)

那么最理想情况下,单机可以承受的最大TCP连接量为:

2^32(local IP) x 2^16(local Port) x 2^32(remote IP) x 2^16(remote Port)

但是就目前的TCP协议来说,显然这是不可能的,首先,不会有一台机器可以占用所有的ip,其次需要考虑机器是否能正常的打开2^16个端口,以及机器是否支持那么多的打开文件,最最最重要的是,机器能否有那么大的内存和CPU资源来维护这些TCP连接。

  1. 内存

因为Linux每维护一条TCP连接都要花费资源。处理连接请求,保活,数据的收发,以及TCP保证可靠传输的各种机制都需要消耗CPU资源,维持TCP连接主要消耗内存。

我们题目的问题是考虑最大多少个连接,所以我们先不考虑数据的收发。

那么TCP在静止的状态下,就不怎么消耗CPU了(先不考虑心跳包保活的问题),主要消耗内存。而Linux上内存是有限的。

一条TCP连接如果不发送数据的话,消耗内存是3.3K左右。

如果有数据发送,需要为每条TCP分配发送缓存区,大小受参数net.ipv4.tcp_wmem配置影响,默认情况下最小是4K

假设你只保持连接不发送数据,那么你服务器可以建立的连接最大数量 = 你的内存/3.3K。 假如是4GB的内存,那么大约可接受的TCP连接数量是100万左右。

对于提供单一服务的具体的服务器来说,不考虑端口复用(unix/linux的SO_REUSEADDR选项)的情况下,例如对于一台nginx Server,它的IP和端口是固定的。tcp连接4元组中只有remote ip(也就是client ip)和remote port(客户端port)是可变的。它理论上可能建立的最大的连接数是2的32次方(ip数)×2的16次方(port数),大约两百万亿!

Linux上除了监听80以外,还可以监听其它的端口,例如mysql的3306, Redis的6339,当然条件允许的话所有65535个端口你都可以用来监听一遍。

以上是关于一台Linux机器上最多能建立多少个TCP连接?的主要内容,如果未能解决你的问题,请参考以下文章

zookeeper一台机器上最多能启动多少个ZooKeeper客户端

漫画 | 一台Linux服务器最多能支撑多少个TCP连接?

漫画:一台 Linux 服务器最多能支撑多少个 TCP 连接

最多能创建多少个 TCP 连接?

最多能创建多少个 TCP 连接?

最多能创建多少个 TCP 连接?