在网络开发中,一台服务器最大究竟能支持多少个网络连接?

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

能处理多少并发其实和每条并发上的数据处理工作量有关,逻辑简单的处理的就多!

假设只建立连接不发送不接收,那么服务器对CPU的需求很少,只是处理握手包的时候才需要一点点。但是没维持一条TCP连接,都需要创建一个文件对象。Linux在系统级、用户级、进程级都有最大可打开文件数量限制!

 

"进程每打开一个文件(linux下一切皆文件,包括socket),都会消耗一定的内存资源。如果有不怀好心的人启动一个进程来无限的创建和打开新的文件,会让服务器崩溃。所以linux系统出于安全角度的考虑,在多个位置都限制了可打开的文件描述符的数量,包括系统级、用户级、进程级。这三个限制的含义和修改方式如下:"

  • 系统级:当前系统可打开的最大数量,通过fs.file-max参数可修改
  • 用户级:指定用户可打开的最大数量,修改/etc/security/limits.conf
  • 进程级:单个进程可打开的最大数量,通过fs.nr_open参数可修改

把上面的参数都调整到100w,每一条TCP连接都需要file、stocket等内核对象,一条空TCP连接共计消耗3.3KB左右。4个GB内存情况下能维持100w条长空连接。对于新发送数据的连接,需要再TCP内核对象上再开启接收缓存区,增加内存开销!

接收缓存区大小是可以配置的,通过sysctl命令就可以查看。

$ sysctl -a | grep rmem
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分配发送缓存区的大小受参数net.ipv4.tcp_wmem配置影响。"

$ sysctl -a | grep wmem
net.ipv4.tcp_wmem = 4096 65536 8388608
net.core.wmem_default = 212992
net.core.wmem_max = 8388608

 "在net.ipv4.tcp_wmem"中的第一个值是发送缓存区的最小值,默认也是4K。当然了如果数据很大的话,该缓存区实际分配的也会比默认值大。"

如果TCP连接上发送接收很多,再加上业务计算逻辑也比较复杂的话,别说100w了,可能1000并发也难!