Linux服务器支持TCP连接的探索
Posted 清晨丶暖阳
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Linux服务器支持TCP连接的探索相关的知识,希望对你有一定的参考价值。
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模型 | 系统崩溃 |
以上是关于Linux服务器支持TCP连接的探索的主要内容,如果未能解决你的问题,请参考以下文章