单服务器TCP百万连接测试的三个限制

准备工作

ubuntu 虚拟机

测试流程

服务器:使用epoll,接收所有连接,看是否能到达1M的连接数。
客户端:就是一个简单的while循环,循环只做一件事,就是申请一个socket然后connect()
不断输出连接数看看能到达多少。

测试1

启动服务器绑定9911端口,启动client连接,发现只能保持1k左右的连接。
在这里插入图片描述

限制1: 最大打开的 fd

原因就在于shell 进程的最大打开文件fd,用于通信的clientfd也算,可以查看最大支持的fd数量是多少,使用 ulimit -n 查看。

ulimit -n

在这里插入图片描述
发现是1024,所以被限制在了1024。

解决方式

通过改个大的值,同样的客户端也需要修改。(这个方法只在这个shell下生效)

ulimit -n 1048576

测试2

解决了fd限制的问题之后,继续测试。
客户端在连接到大2w8左右的时候connect()出错了,打印errno看看是99,cannot assign requested address,说明端口耗尽(实际上只是客户端对服务器的那个端口的组合耗尽了,客户端如果连接其他端口还能继续用,没有影响)。
在这里插入图片描述

限制2: 端口限制

TCP连接靠的是 sock 进行通信,每一个TCP使用的socket对应一个四元组(也就是一个连接) (源IP, 源Port,目的IP, 目的Port),要建立不同连接就需要改变这个四个中的一个,因为是同一台主机(我只用了一个IP),所以只能改变端口了。

可用端口可通过命令查看:

cat /proc/sys/net/ipv4/ip_local_port_range

在这里插入图片描述
可以看到这台虚拟机最多只能用 2w8 左右个端口。服务器绑定一个端口9911,客户端最多2w8个端口可用,连接最大只能到 1 * 2w8 = 2w8。
在这里插入图片描述
那么怎么才能多创建几个连接呢,如果服务端多几个端口,组合数就多了,sock对应的四元组组合(连接)就多了,如图:多了蓝色的几个连接。
在这里插入图片描述

解决方式

服务器多监听几个端口试试
这里在服务端创建了100个listenfd,绑定在100个不同的端口上,把这些listenfd都放到epoll里面去。客户端在connect失败之后就换一个服务器的端口进行connect(),结果如下,可以看到已经超过了可用端口数2w8.
在这里插入图片描述

测试3

上面已经超过了2w8(可用端口数),但是在连接停止在6w5左右。
在这里插入图片描述

限制3: nf_conntrack_max

解决了前两个限制,还有一个限制就是 nf_conntrack_max,当连接超过设定值(65535)的时候就无法连接上了,服务器配置问题。

Linux 内核中有一个内核模块 nf_conntrack 用于做连接跟踪,当 iptables 添加了 nat 相关规则时此模块会被自动启用。net.netfilter.nf_conntrack_max: 连接跟踪表最大值,超出后会导致操作系统会丢包。默认为 65535,优化至 6553500。

– 引用《https://xie.infoq.cn/article/c271f0b17cc3b0cf2c2f7f73c》

查看nf_conntrack_max的命令:

sysctl -a | grep nf_conntrack_max
# 输出:
# net.netfilter.nf_conntrack_max = 65535
# net.nf_conntrack_max = 65535

解决方式

vi /etc/sysctl.conf
# 添加一行 
net.netfilter.nf_conntrack_max = 1048576
# 执行下列命令使其生效
sysctl -p

再次测试:
20W连接,内存只有100M了,很慢了,没时间等了,就不继续往下了,维护TCP连接用了大概 1600M的内存。。。
在这里插入图片描述

一些常用知识

  • 调整最大打开fd
#以下两个是进程级别的
# vi /etc/sysctl.conf
fs.nr_open=1100000  //要比 hard nofile 大一点
# sysctl -p(生效)
# vi /etc/security/limits.conf
*  soft  nofile  1000000
*  hard  nofile  1000000

# file-max 是系统级别的
fs.file-max=1100000
  • 查看进程号为 pid 的进程打开的fd
ls /proc/{
   
   pid}/fd/

测试代码

epoll服务器测试代码。

g++ test_server.cpp -o server
./server server_port
#include <unistd.h>
#include <sys/types.h>
#include <cstring>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <sys/epoll.h>
#include <iostream>
#include <signal.h></
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值