51工具盒子

依楼听风雨
笑看云卷云舒,淡观潮起潮落

阿里真实三面:一个服务器程序,最大支持的TCP连接数是多少?

引言 上一篇研究了,一台电脑最多可以开启多少个客户端进程?这一篇研究 一个服务器程序,最大支持的TCP连接数是多少? 如何确定一个TCP连接? 首先我们要知道TCP连接的本质在内核里面是一个socket对象。 查找linux内核源码net目录下 ``` C                   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、目标端口。 \| ![](https://img1.51tbox.com/static/2024-06-04/col/381b3afe652e8e75c5255d0cd498d61b/a65b2859eea147d0b1885e6f15494770.jpg) 所以一个TCP连接是由 【源IP、源端口、目标IP、目标端口】这四个信息确定的,有了这4个信息就能在系统内核当中找到这个socket对象。 服务器程序的IP和端口 一个服务器程序通常是监听一个端口号(也有监听多个端口的情况,我们这里只考虑监听一个端口),比如你开发的游戏程序,对外提供一个端口30188,客户端访问这个端口就可以进行登陆游戏操作。 ![](https://img1.51tbox.com/static/2024-06-04/col/381b3afe652e8e75c5255d0cd498d61b/43c028a5ee034fa3a11f02ce2bed0792.jpg) 可以看到这个程序在30188端口进行监听,与此同时也能看到绑定了 0.0.0.0 IP地址。 所以一个服务器程序,它的IP地址和端口号是固定的(0.0.0.0:30188) 0.0.0.0 IP地址表示啥?为什么很多服务器程序绑定 0.0.0.0? 0.0.0.0 IP地址在互联网协议(IP)中是一个特殊的地址。它通常用于表示"本网络中的这个主机",即本地主机。在不同的上下文中,0.0.0.0有不同的含义: 服务器绑定:当服务器程序绑定到0.0.0.0地址时,它实际上是在告诉操作系统监听所有可用的网络接口上的入站连接。这意味着无论数据从哪个网络接口进入(比如以太网接口、Wi-Fi接口等),服务器都能接受这些连接。这样做可以让服务器接受来自任何网络接口的连接,从而确保不会因为绑定到特定的接口而错过任何连接请求。 路由:在路由环境中,0.0.0.0可能表示一个默认路由或者是一个无效的目的地址。默认路由指的是当路由表中没有匹配特定目的地址的路由条目时,数据包应该被发送到的路由器。 客户端配置:在某些客户端配置中,0.0.0.0可能用作一个占位符,表示没有有效的IP地址配置,或者表示客户端应该使用自动IP地址分配(比如DHCP)来获取IP地址。 安全:在安全设置中,0.0.0.0有时被用来表示不应该监听任何网络接口,或者不应该允许任何来自外部的连接。 当服务器程序绑定到0.0.0.0时,它能够更加灵活地服务于多个网络接口,这对于希望接受来自任何网络源的连接的服务器来说是非常有用的。同时,它也简化了服务器配置,因为不需要为每个网络接口单独配置监听端口。 一个服务器程序的理论最大TCP连接数 通过上面的内容我们可以知道:当客户端与服务端建立一条 TCP 连接的时候,这个 TCP 连接的四元组信息中服务端的 IP地址和端口号是固定的,能产生变化的就是客户端的 IP 地址和端口号了。 因此,一个服务器程序最大能支持的TCP连接个数应该是: ![](https://img1.51tbox.com/static/2024-06-04/col/381b3afe652e8e75c5255d0cd498d61b/6ae2f1c69d874b5ba54b0483a8114b64.jpg) 对于IPV4,客户端IP数最多为2的32次方,客户端端口数最多为2的16次方。 那么一个服务器程序的理论最大连接数为2的48次方,约等于两百万亿! 一个服务器程序的实际TCP连接数 实际上,一个服务器程序实际最大能支持的TCP连接数远不能达到理论值,还会受到文件描述符、内存等硬件方面的影响。 文件描述符限制 每个 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 一条处于 ESTABLISH 状态的 空闲TCP 连接具体占用多大内存? 一个 TCP 对象占用的大小,等于它所包含的一些数据结构占用大小的总和,也就是把上面这些数据结构的大小累加起来,就是一个 TCP 连接占用的大小了。计算下来一天处于ESTABLISH状态的初始空闲的TCP连接占用的大小大概是3.44KB。 创建⼀个socket 需要消耗 densty、flip、sock_inode_cache、TCP 四个内核对象。这些对象加起来总共需消耗⼤约 3 KB 多⼀点的内存。如果连接上有数据收发的话,还需要消耗发送、接收缓存区。这两个缓存区占⽤内存影响因素⽐较多,既受收发数据的⼤⼩,也受 tcp_rmem、tcp_wmem 等内核参数,还取决于服务器进程能否 及时接收(及时接收的话缓存区就能回收) ![](https://img1.51tbox.com/static/2024-06-04/col/381b3afe652e8e75c5255d0cd498d61b/4784fd0607e546f2a92b187426314015.jpg) 8G内存实际支持的最大TCP连接数 每条空闲的TCP连接大约占3.44K的内存 那么8GB内存的服务器,最大支持的TCP连接数 = 8GB/3.44KB 约等于240万 但是实际生产环境,TCP连接很多都是活的,很难达到百万级别。 总结 \|------------------------\| \| 一个服务器程序最大支持的TCP连接数是多少? \| 在不考虑服务器的内存和文件描述符的情况下,理论上一个服务端进程最多能支持约为 2 的 48 次方(2\^32 (ip数) \* 2\^16 (端口数),约等于两百多万亿! 在实际中很难达到理论值甚至相差甚远,每个 TCP 连接都是一个文件,会占用文件句柄资源,也会占用一定的内存空间。 题外话: 推荐候捷老师全套课程 ![](https://img1.51tbox.com/static/2024-06-04/col/381b3afe652e8e75c5255d0cd498d61b/0fa91c1243254bfb9905ec3227eff302.jpg) **扫描下面二维码获取441F** ![](https://img1.51tbox.com/static/2024-06-04/col/381b3afe652e8e75c5255d0cd498d61b/3c6dd66e378c4132bd56b259b6acff5a.jpg)
赞(4)
未经允许不得转载:工具盒子 » 阿里真实三面:一个服务器程序,最大支持的TCP连接数是多少?