Linux服务器支持TCP连接的探索

一、如何统计可建立的TCP连接数

"TCP连接四元组是源IP地址、源端口、目的IP地址和目的端口。任意一个元素发生了改变,那么就代表的是一条完全不同的连接了。拿我的Nginx举例,它的端口是固定使用80。另外我的IP也是固定的,这样目的IP地址、目的端口都是固定的。剩下源IP地址、源端口是可变的。所以理论上我的Nginx上最多可以建立2的32次方(ip数)×2的16次方(port数)个连接。这是两百多万亿的一个大数字!!"


在这里插入图片描述
若一个客户端建立大量连接时,并全是目标IP的一个端口,那么可能就出现错误。
在这里插入图片描述
无法分配请求地址:端口不够用。

### 查看端口号
cat /proc/sys/net/ipv4/ip_local_port_range 
1024 65000

二、TCP连接所受限制

实际上:处理并发的数量是根据每条并发上数据处理的工作量决定的,因为处理的数据量受到性能的限制。
其实不然,除了CPU性能,还有可创建文件对象的数量也会限制TCP连接的数量(创建一条TCP连接就需要创建一个文件,而操作系统限制文件对象的数量)。

Linux系统在系统级、用户级、进程级都有最大可打开文件数量限制。

在这里插入图片描述

进程每打开一个文件(linux下一切皆文件,包括socket),都会消耗一定的内存资源。

如果有不怀好心的人启动一个进程来无限的创建和打开新的文件,会让服务器崩溃。所以linux系统出于安全角度的考虑,在多个位置都限制了可打开的文件描述符的数量,包括系统级、用户级、进程级。

这三个限制的含义和修改方式如下:

  • 系统级:当前系统可打开的最大数量,通过fs.file-max参数可修改

  • 用户级:指定用户可打开的最大数量,修改/etc/security/limits.conf

  • 进程级:单个进程可打开的最大数量,通过fs.nr_open参数可修改

### 接收缓存区大小是可以配置的,通过sysctl命令就可以查看
$ sysctl -a | grep rmem
## 4096可直接影响TCP分配发送缓存区大小
net.ipv4.tcp_rmem = 4096 87380 8388608
net.core.rmem_default = 212992
net.core.rmem_max = 8388608

## tcp_rmem"中的第一个值是为你们的TCP连接所需分配的最少字节数。该值默认是4K,最大的话8MB之多。也就是说你们有数据发送的时候我需要至少为对应的socket再分配4K内存,甚至可能更大。

操作系统接收的数据包需要经过内核协议栈处理,接收数据和发送数据都需要缓冲区,所以也需要消耗CPU进行发送。

在这里插入图片描述

## 查看TCP的连接数
ss -n | grep ESTAB | wc -l  
1000024
## 内核Slab占用,MemFree和Buffers剩余内存
$ cat /proc/meminfo
MemTotal:        3922956 kB
MemFree:           96652 kB
MemAvailable:       6448 kB
Buffers:           44396 kB
......
Slab:          3241244KB kB
slabtop命令可以查看到densty、flip、sock_inode_cache、TCP四个内核对象

总结整理

问题一:端口号资源

在这里插入图片描述
当同一个客户端建立大量连接时,会报错:表示端口号不够用啦!一个劲地对着同一个 IP 和端口创建 TCP 连接,端口号不够用了,源端口那里没法给了。
可是知道端口号是 16 位的,范围是 1~65535,一共可以创建 65535 个 TCP 连接,Linux 对可使用的端口范围是有具体限制的

### 查看端口范围
cat /proc/sys/net/ipv4/ip_local_port_range

问题二:文件描述资源

在这里插入图片描述
每维持一条TCP连接,就需要建立一个文件,Linux系统中文件数量是受限制的,而且传输数据的过程中,文件内存就会提升,一旦超过系统内存,系统就会崩溃。

进程每打开一个文件(linux下一切皆文件,包括socket),都会消耗一定的内存资源。消耗过多内存会让服务器崩溃。

三个限制文件数的含义和修改方式如下:

系统级:当前系统可打开的最大数量,通过fs.file-max参数可修改

用户级:指定用户可打开的最大数量,修改/etc/security/limits.conf

进程级:单个进程可打开的最大数量,通过fs.nr_open参数可修改

问题三:线程资源

办事效率越来越慢,建立一个TCP连接花的时间越来越久。因为大量线程在不停进行上下文切换,消耗了大量内存。
在这里插入图片描述

C10K 问题,就是当服务器连接数达到 1 万且每个连接都需要消耗一个线程资源时,操作系统就会不停地忙于线程的上下文切换,最终导致系统崩溃。

可以使用IO多路复用方式:一个线程可以管理多个 TCP 连接的资源,这样你就可以用少量的线程来管理大量的 TCP 连接。

在这里插入图片描述

问题四:CPU资源

在这里插入图片描述
错误叫内存溢出:每个TCP连接本身,以及这个连接所用到的缓冲区,都是需要占用一定内存的,现在内存(CPU暴毙了)已经被你占满了,不够用了,所以报了这个错。此时只能加大服务器内存或者kill无用进程了。

问题总结

资源

一台Linux服务器的资源

一个TCP连接占用的资源

占满了会发生什么

CPU

看你花多少钱买的

看你用它干嘛

电脑卡死

内存

看你花多少钱买的

取决于缓冲区大小

OOM

临时端口号

ip_local_port_range

1

cannot assign requested address

文件描述符

fs.file-max

1

too many open files

进程\线程数

ulimit -n

看IO模型

系统崩溃

![在这里插入图片描述](https://img-blog.csdnimg.cn/20210701125854575.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM5ODg2OTc1,size_16,color_FFFFFF,t_70)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值