正文
一个TCP连接 需要 CPU资源、内存资源、端口号资源、文件描述符资源、线程资源。
资源 一台Linux服务器的资源 一个TCP连接占用的资源 占满了会发生什么
CPU 看你花多少钱买的 看你用它干嘛 电脑卡死
内存 看你花多少钱买的 取决于缓冲区大小 OOM
临时端口号 ip_local_port_range 1 cannot assign requested address
文件描述符 fs.file-max 1 too many open files
进程\线程数 ulimit -n 看IO模型 系统崩溃
最多能创建多少个 TCP 连接,取决于最先触达的那个限制条件。理论上TCP连接没有上限。
端口号
建立一个 TCP 连接,需要将通信两端的套接字(socket)进行绑定,如下:
源 IP 地址:源端口号
<—-> 目标 IP 地址:目标端口号
系统知道有哪些网卡,即知道源IP,会随机分配一个 16位(0-65535) 内的源端口号。
Linux 对可使用的端口范围是有具体限制的,具体可以用如下命令查看:
[root]# cat /proc/sys/net/ipv4/ip_local_port_range
1024 65000
解决办法是 修改范围,不过不能突破65535:
vim /etc/sysctl.conf
添加一行,如(限定为10个源端口):
net.ipv4.ip_local_port_range = 60000 60009
保存好后执行下面命令,使其生效:
sysctl -p /etc/sysctl.conf
对同一 源IP地址
、目标IP地址:目标端口号
,最多只能建立上面文件限定的连接数(客户端系统随机分配 源端口号
)。
如果 对不同的 目标IP地址:目标端口号
,同一个 源IP地址
也可以建立无数的连接,完全不存在所谓的 65535 个连接限制的条件。
文件描述符
linux 下一切皆文件,对目标 IP 进行 TCP 通信的时候,就是对着 TCP连接 返回的 文件描述符 进行读写。
linux 对可打开的文件描述符的数量分别作了三个方面的限制:
系统级:当前系统可打开的最大数量,通过 cat /proc/sys/fs/file-max
查看
用户级:指定用户可打开的最大数量,通过 cat /etc/security/limits.conf
查看
进程级:单个进程可打开的最大数量,通过 cat /proc/sys/fs/nr_open
查看
如:
[root ~]# cat /proc/sys/fs/file-max
100000
[root ~]# cat /proc/sys/fs/nr_open
100000
[root ~]# cat /etc/security/limits.conf
...
* soft nproc 100000
* hard nproc 100000
解决办法 是 修改 限制条件。
修改单个进程可打开的最大文件描述符限制为100,可以这样:
echo 100 > /proc/sys/fs/nr_open
你完全可以加个0 改大。
线程
每建一个TCP连接都需要消耗一个线程,随着线程数的增加,线程间会切换越来越慢。
C10K 问题,就是当服务器连接数达到 1 万且每个连接都需要消耗一个线程资源时,操作系统就会不停地忙于线程的上下文切换,最终导致系统崩溃。
解决办法是 IO多路复用:将原来的 TCP 连接销毁掉,改成同一个线程管理多个 TCP 连接。
内存
内存溢出,每个TCP连接本身,以及这个连接所用到的缓冲区,都是需要占用一定内存的,内存已经被占满,不够用了。
解决办法是 扩大内存,手段有:加内存条、杀死特别占内存的进程。
CPU
CPU 的占用率到 100%,无法继续服务。
参考资料
最多能创建多少个 TCP 连接? https://mp.weixin.qq.com/s/X6c_H5_4OInR8nFQVn7IMA
最多能创建多少个 TCP 连接? https://mp.weixin.qq.com/s/YgOvUVNuaxcasLo0DdhhmA
你管这破玩意叫 IO 多路复用? https://mp.weixin.qq.com/s/YdIdoZ_yusVWza1PU7lWaw
图解 深入揭秘 epoll 是如何实现 IO 多路复用的! https://mp.weixin.qq.com/s/OmRdUgO1guMX76EdZn11UQ