LibProNet单进程处理400万TCP长连接的测试

一、前言

LibProNet是一个开源的C++网络通信引擎,它由一套网络库、一个消息框架和一些有用的网络编程套件构成。与其他著名的网络库诸如libevent/libuv/asio相比,LibProNet更加简洁清晰,容易使用。

LibProNet的工程地址为:https://github.com/libpronet/libpronet

我们今天测试的是LibProNet的网络库模块,目的是为了验证一下该模块的性能和能力参数。测试平台采用青云服务器和Ubuntu操作系统,测试工具采用LibProNet里的TestTcpServer和TestTcpClient程序。

二、测试过程

我们关心的是400万TCP长连接的情况下,服务端程序的表现,比如CPU消耗、内存消耗等,客户端只是起配合的作用。因此服务端要求环境比较干净,不能有其他的程序干扰。我们使用两台测试机,一台运行服务端,一台运行客户端。由于是海量连接,每个TCP地址最多能发起60000多个连接,为了达到400万连接,我们需要在客户机上创建虚拟网卡。每块虚拟网卡发起60000个连接,大概需要创建70块虚拟网卡。

1、申请主机资源

测试参数里,我们为每个套接字设置2048字节的发送缓冲区,2048字节的接收缓冲区,以及2048字节的接收池。考虑带些冗余,每个链路消耗的内存应该不会超过8K,400万链路即便不考虑虚拟内存交换,至多消耗32G物理内存,我们申请48G内存的主机应该是足够了。默认情况下,青云服务帐户有CPU核心数和内存配额的限制,大概是总共10个核心,总共40G内存,如果增加配额,需要提交身份认证。为了完成测试,上传证件,完成认证,之后CPU核心数和内存配额就足够测试使用了。

先申请两台如下配置的主机:
LibProNet单进程处理400万TCP长连接的测试_第1张图片
再申请一个交换机,并将两台主机与交换机相连:
LibProNet单进程处理400万TCP长连接的测试_第2张图片
外加一台路由器:
LibProNet单进程处理400万TCP长连接的测试_第3张图片
并将交换机连接到路由器:
LibProNet单进程处理400万TCP长连接的测试_第4张图片
接下来启动主机,通过Web页面的远程控制工具进入Linux系统,为了方便后续的测试,我们通过sudo su命令进入管理员模式。先看一下CPU配置:
LibProNet单进程处理400万TCP长连接的测试_第5张图片
此外,为了下载代码和编译工具,我们还需要申请一个公网IP,并将公网IP绑定到路由器上。这样,两台主机就可以通过路由器连接外网了。

系统就绪后,Server主机的IP地址为192.168.0.201,Client主机的IP地址为192.168.0.202。

2、配置测试环境

为了支持海量连接,我们需要修改Linux系统配置,以便允许打开大量的文件句柄。我们保持在一个控制台终端里进行测试,执行以下命令:

sysctl -w fs.file-max=4100000
cat /proc/sys/fs/file-max
cat /proc/sys/fs/file-nr

sysctl -w fs.nr_open=4100000
cat /proc/sys/fs/nr_open
echo "* soft nofile 4100000" >> /etc/security/limits.conf
echo "* hard nofile 4100000" >> /etc/security/limits.conf
ulimit -n 4100000
ulimit -n

sysctl -w net.ipv4.ip_local_port_range="1024 65535"
cat /proc/sys/net/ipv4/ip_local_port_range

现在,如果命令行里没有提示错误,那么海量连接就允许了。注意不要重启机器,否则就要重新执行上述命令了,因为我们没有做永久设置。

另外,在Client主机里,我们需要创建70块虚拟网卡,命令如下:

ifconfig eth0:0 192.168.0.100 netmask 255.255.255.0 up
ifconfig eth0:1 192.168.0.101 netmask 255.255.255.0 up
ifconfig eth0:2 192.168.0.102 netmask 255.255.255.0 up
......
ifconfig eth0:69 192.168.0.169 netmask 255.255.255.0 up
ifconfig eth0:70 192.168.0.170 netmask 255.255.255.0 up

为了便于记忆,我们创建了71块虚拟网卡,第一行的eth0:0占个位,我们不使用它。

3、运行测试程序

现在,运行测试的操作系统环境准备好了,剩下的工作就是下载和编译代码了。我们需要安装必要的开发工具,比如git/gcc/g++/automake/make等。

apt-get update
apt-get install autoconf automake gcc g++ make git-core screen nload

下载代码:

cd /
mkdir test
cd test
git clone https://github.com/libpronet/libpronet.git   

编译代码:

cd libpronet/build/linux-gcc-r/x86_64
chmod 777 *.sh
./autogen.sh
make

准备运行目录:

cd ../../../pub/lib-r
chmod 777 *.sh
./_get-linux-x86_64.sh
cd ../../run_box
chmod 777 *.sh
./_get-linux-x86_64-r.sh

至此,运行目录就准备好了。为了便于在终端里切换上下文,我们让测试程序运行在screen环境里。对于服务端而言,只有一个服务进程,我们只需要创建一个screen会话就可以了,然后在这个会话环境里启动test_tcp_server程序;对于客户端而言,由于要创建70个测试进程,所以需要启动70个screen会话,在每个会话里运行一个test_tcp_client进程,各个进程分别绑定到192.168.0.101~192.168.0.170的IP地址。

服务端:

screen -S myserver #创建一个screen会话,名字叫myserver
./test_tcp_server  #在myserver会话里运行服务端程序
Ctrl-A,D          #按Ctrl-A组合键,再释放,再按D键,把screen切到后台,回到shell

客户端需要先用vi修改一下test_tcp_client.cfg文件,把服务器地址tcpc_server_ip的值改为192.168.0.201,把连接数tcpc_connection_count的值改为60000,其他保持默认。

screen -S myclient01
./test_tcp_client 0 0 192.168.0.101
Ctrl-A,D

screen -S myclient02
./test_tcp_client 0 0 192.168.0.102
Ctrl-A,D
......
screen -S myclient70
./test_tcp_client 0 0 192.168.0.170
Ctrl-A,D

注意控制一下并发节奏,一段时间后,连接就都建好了。

4、测试数据之一

我们可以在服务端动态查看实际的在线连接数,先回到screen会话:

screen -r myserver

然后直接按回车即可显示目前服务端的状态:
LibProNet单进程处理400万TCP长连接的测试_第6张图片

可以看到,一共40个线程,420万连接。我们切到shell看一下系统资源消耗:

Ctrl-A,D

ps统计数据:
在这里插入图片描述
vmstat统计数据:
LibProNet单进程处理400万TCP长连接的测试_第7张图片
top统计数据:
LibProNet单进程处理400万TCP长连接的测试_第8张图片
nload统计数据:
LibProNet单进程处理400万TCP长连接的测试_第9张图片
再到Web云控制台看一下统计信息:
LibProNet单进程处理400万TCP长连接的测试_第10张图片
为了直观显示,我们把四条占用数据都集合到一个图里了。可以看出,服务器的资源足够,远远没有用完呢!客户端的CPU消耗比较高些,是因为进程太多了,70个进程,每个进程10个工作线程,总体切换比较厉害。不过因为客户端只是这里的配角,我们不管它了。

通过资源消耗估计,服务端应该还可以支持更多的链路,不过我们就不继续测试它了。

5、测试数据之二

上面的测试数据是在链路心跳包为200字节的情况下的数据,流量压力并不大。那我们加大一些数据压力会怎样呢。出于简单,我们修改一下服务端的心跳包大小,改为1000字节。这可以在服务端程序的控制台里,动态修改,命令如下:

screen -r myserver
htbtsize 1000

LibProNet单进程处理400万TCP长连接的测试_第11张图片
然后再看一下各项参数,vmstat:
LibProNet单进程处理400万TCP长连接的测试_第12张图片
top:
LibProNet单进程处理400万TCP长连接的测试_第13张图片
nload:
LibProNet单进程处理400万TCP长连接的测试_第14张图片
通过nload我们可以看到,目前的平均发送带宽达到了60.03MBit/s,但CPU和内存占用变化不大。

上述测试过程我们保持平稳运行了几个小时,通过分析测试数据,我们认为LibProNet的网络库还是很优异的,完全可以胜任海量系统的底层数据引擎。当然了,长期的生产环境测试才是最有意义的。

你可能感兴趣的:(网络编程,服务器,多线程,LibProNet)