一台服务器,最大支持的TCP连接数是多少?

大家好,我是小林。
最近有读者面试腾讯的时候,被问到 2 个很有意思的问题:
一个服务端进程最大能支持多少条 tcp 连接?
一台服务器最大能支持多少条 tcp 连接?
很多同学第一反应就是端口的限制,端口号最多是 65536个,那就最多只能支持 65536 条 tcp 连接。
实际上这是不对的!
今天都带大家分析一波这两个问题。
一个服务端进程最多能支持多少条 tcp 连接?
首先我们要知道 tcp 连接本质上在内核里就是一个 socket 对象。
struct socket {      ....    //inet域专用的一个socket表示, 提供了inet域专有的一些属性,比如 ip地址,端口等    struct sock             *sk;      //tcp连接的状态:syn_sent、syn_recv、established.....    short                   type;      ....};  struct inet_sock {  ...  __u32    daddr;   //ipv4的目标地址。    __u16    dport;   //目标端口。     __u32    saddr;   //源地址。    __u16    sport;   //源端口。  ...};    
这个 socket 对象也就是一个数据结构,里面包含了 tcp 四元组的信息:源ip、源端口、目标ip、目标端口。
tcp 四元组
所以, 只要确认了【源ip、源端口、目标ip、目标端口】这四个信息,就能在内核中找到这个 socket 对象,也就能确定一条 tcp 连接。
一个服务端进程通常是监听 1 个端口号(当然也可能监听多个端口号,这里不考虑),比如我的图解网站的 nginx 服务,就监听了 443 端口。
你们看图解网站的时候,实际上就是通过 nginx 服务把网页数据发送给你们的。
然后,服务端进程除了会固定监听某个一个端口之外,也通常会绑定 0.0.0.0 ip 地址。
这个ip地址是特殊的, 0.0.0.0 指的是本机上的所有ipv4地址,如果一个主机有两个 ip 地址,192.168.1.1 和 10.1.2.1,并且该主机上的一个服务监听的地址是0.0.0.0,那么通过两个 ip 地址都能够访问该服务。
所以一个服务端进程,意味着他的 ip地址和端口号是固定的(0.0.0.0:443)。
也就是当客户端与服务端建立一条 tcp 连接的时候,这个 tcp 连接的四元组信息中服务端的 ip地址和端口号是固定的,能产生变化的就是客户端的 ip 地址和端口号了。
因此,一个服务端进程最大能支持的 tcp 连接个数的计算公式如下:
对 ipv4,客户端的 ip 数最多为 2 的 32 次方,客户端的端口数最多为 2 的 16 次方。
那么一个服务端进程理想情况下,最大的 tcp 连接数约为 2 的 48 次方(2^32 (ip数) * 2^16 (端口数),这数值是非常夸张的了,约等于两百多万亿!
当然,服务端进程最大能支持的 tcp 连接数远不能达到理论上限,还会受到文件描述符、内存大小资源的限制,毕竟 socket 在 linux 的视角其实就是文件资源,而且一个 socket 对象也会占用一定的内存资源。
因此,会受以下因素影响:
文件描述符限制,每个 tcp 连接都是一个文件,如果文件描述符被占满了,会发生 too many open files。linux 对可打开的文件描述符的数量分别作了三个方面的限制:
系统级:当前系统可打开的最大数量,通过 cat /proc/sys/fs/file-max 查看;
用户级:指定用户可打开的最大数量,通过 cat /etc/security/limits.conf 查看;
进程级:单个进程可打开的最大数量,通过 cat /proc/sys/fs/nr_open 查看;
内存限制,每个 tcp 连接都要占用一定内存,操作系统的内存是有限的,如果内存资源被占满后,会发生 oom。
一台服务器最大最多能支持多少条 tcp 连接?
前面分析是一个服务端进程理的情况,理论上能最大支持约为 2 的 48 次方(2^32 (ip数) * 2^16 (端口数),约等于两百多万亿!
那到了一台服务器的视角就会有一点不一样。
一台服务器是可以有多个服务端进程的,每个服务端进程监听不同的端口,比如:ssh的22,redis的6339,当然所有65535个端口你都可以用来监听一遍。
当然所有65535个端口你都可以用来监听一遍,这样理论上线就到了2的32次方(ip数)×2的16次方(port数)×2的16次方(服务器port数)个,感兴趣你可以算一下,这个基本相当于无穷个了。
不过理想和实际总是会有差距的!
因为linux每维护一条tcp连接都要花费资源,处理连接请求,保活,数据的收发时需要消耗一些cpu,维持tcp连接主要消耗内存。
我们题目的问题是考虑最大多少个连接,所以我们先不考虑数据的收发,那么tcp在静止的状态下,就不怎么消耗cpu了,主要消耗内存,而linux上内存是有限的。
首先,我们要知道一条处于 establish 状态的 tcp 连接具体占用多大内存?
一个 tcp 对象占用的大小,等于它所包含的一些数据结构占用大小的总和,也是就把上面这些数据结构的大小累加起来,就是一个 tcp 连接占用的大小了。
这里直接给大家一个结论,一条处于 establish 状态的 tcp 连接占用的大小是 3.44 kb(0.81k+2.19k+0.19k+0.25k)。
tcp对象内存开销总结
也就是,每一条静止状态的tcp连接大约需要吃 3.44k 的内存。
那么 8 gb 物理内存的服务器,最大能支持的 tcp 连接数=8gb/3.44kb=2,438,956(约240万)!
当然, 实际过程中的 tcp 连接,肯定不是静止状态的,还会进行发送数据和接收数据了,那么这些过程还是会额外消耗更多的内存资源的,并发很难达到百万级别。
总结
一个服务端进程最多能支持多少条 tcp 连接?
如果在不考虑服务器的内存和文件句柄资源的情况下,理论上一个服务端进程最多能支持约为 2 的 48 次方(2^32 (ip数) * 2^16 (端口数),约等于两百多万亿!
但是在实际中是支持不了这个数值的,每个 tcp 连接都是一个文件,会占用文件句柄资源,也会占用一定的内存空间。
一台服务器最大最多能支持多少条 tcp 连接?
一台服务器是可以有多个服务端进程的,每个服务端进程监听不同的端口,当然所有65535个端口你都可以用来监听一遍。
当然所有65535个端口你都可以用来监听一遍,这样理论上线就到了2的32次方(ip数)×2的16次方(port数)×2的16次方(服务器port数)个,这个基本相当于无穷个了。
但是 linux每维护一条tcp连接都要花费内存资源的,每一条静止状态(不发送数据和不接收数据)的 tcp 连接大约需要吃 3.44k 的内存,那么 8 gb 物理内存的服务器,最大能支持的 tcp 连接数=8gb/3.44kb=2,438,956(约240万)。
实际过程中的 tcp 连接,还会进行发送数据和接收数据了,那么这些过程还是会额外消耗更多的内存资源的,并发很难达到百万级别。


星星之火,可以燎原——关于太赫兹的技术进展
为微控制器增加PWM/模拟通道的方法
使用Word经常会碰到的小问题解决方法详细说明
变频器故障代码有哪些
存储器的涨价会是拐点吗
一台服务器,最大支持的TCP连接数是多少?
助焊剂有铅与无铅有什么区别
出国度假族必备黑白双摄
韩联社:Facebook在韩国擅自使用用户信息,被控告并罚款约 3978 万元
无损压缩:最大限度提高帧率并超越 GigE 带宽的限制
中国移动联合中兴通讯完成了基于3GPP R15标准的2.6GHz NR外场测试
英特尔仍在推进折叠屏笔记本电脑的研发,相关的设备有望在今年年底上架
无线传输原理 无线传输模块有哪些
ESD电容电路图分析
数字示波器错误理解测量的检测方案
数控系统在各大工业应用广泛,拥有良好的发展前景
顶级Javaer都在使用的类库!
西门子S7-1200高速计数器功能介绍及应用举例
VisIC Technologies为大功率氮化镓牵引逆变器铺平了道路
平安科技的 AI+教育 星火要燎原了