构建百万级连接的服务器之理论基础与实现Word下载.docx

上传人:b****5 文档编号:19705943 上传时间:2023-01-09 格式:DOCX 页数:9 大小:18.58KB
下载 相关 举报
构建百万级连接的服务器之理论基础与实现Word下载.docx_第1页
第1页 / 共9页
构建百万级连接的服务器之理论基础与实现Word下载.docx_第2页
第2页 / 共9页
构建百万级连接的服务器之理论基础与实现Word下载.docx_第3页
第3页 / 共9页
构建百万级连接的服务器之理论基础与实现Word下载.docx_第4页
第4页 / 共9页
构建百万级连接的服务器之理论基础与实现Word下载.docx_第5页
第5页 / 共9页
点击查看更多>>
下载资源
资源描述

构建百万级连接的服务器之理论基础与实现Word下载.docx

《构建百万级连接的服务器之理论基础与实现Word下载.docx》由会员分享,可在线阅读,更多相关《构建百万级连接的服务器之理论基础与实现Word下载.docx(9页珍藏版)》请在冰豆网上搜索。

构建百万级连接的服务器之理论基础与实现Word下载.docx

filter.ip_conntrack_max=1020000

需要重启系统服务生效:

#Linux

$sudosysctl-p/etc/sysctl.conf

#BSD

$sudo/etc/rc.d/sysctlreload

进程限制

执行:

ulimit-n

输出:

1024

说明当前Linux系统的每一个进程只能最多打开1024个文件.为了支持C1000K,你同样需要修改这个限制.

临时修改

ulimit-n1020000

不过,如果你不是root,可能不能修改超过1024,会报错:

-bash:

ulimit:

openfiles:

cannotmodifylimit:

Operationnotpermitted

永久修改

编辑/etc/security/limits.conf文件,加入如下行:

#/etc/security/limits.conf

workhardnofile1020000

worksoftnofile1020000

第一列的work表示work用户,你可以填*,或者root.然后保存退出,重新登录服务器.

注意:

Linux内核源码中有一个常量(NR_OPENin/usr/include/linux/fs.h),限制了最大打开文件数,如RHEL5是1048576(2^20),所以,要想支持C1000K,你可能还需要重新编译内核.

2.操作系统维持百万连接需要多少内存?

解决了操作系统的参数限制,接下来就要看看内存的占用情况.首先,是操作系统本身维护这些连接的内存占用.对于Linux操作系统,socket(fd)是一个整数,所以,猜想操作系统管理一百万个连接所占用的内存应该是4M/8M,再包括一些管理信息,应该会是100M左右.不过,还有socket发送和接收缓冲区所占用的内存没有分析.为此,我写了最原始的C网络程序来验证:

服务器

#include&

lt;

stdio.h&

gt;

stdlib.h&

string.h&

unistd.h&

errno.h&

arpa/inet.h&

netinet/tcp.h&

sys/select.h&

#defineMAX_PORTS10

intmain(intargc,char**argv){

structsockaddr_inaddr;

constchar*ip="

0.0.0.0"

;

intopt=1;

intbufsize;

socklen_toptlen;

intconnections=0;

intbase_port=7000;

if(argc&

2){

base_port=atoi(argv[1]);

}

intserver_socks[MAX_PORTS];

for(inti=0;

i&

MAX_PORTS;

i++){

intport=base_port+i;

bzero(&

amp;

addr,sizeof(addr));

addr.sin_family=AF_INET;

addr.sin_port=htons((short)port);

inet_pton(AF_INET,ip,&

addr.sin_addr);

intserv_sock;

if((serv_sock=socket(AF_INET,SOCK_STREAM,0))==-1){

gotosock_err;

if(setsockopt(serv_sock,SOL_SOCKET,SO_REUSEADDR,&

opt,sizeof(opt))==-1){

if(bind(serv_sock,(structsockaddr*)&

addr,sizeof(addr))==-1){

if(listen(serv_sock,1024)==-1){

server_socks[i]=serv_sock;

printf("

serverlistenonport:

%d\n"

port);

//optlen=sizeof(bufsize);

//getsockopt(serv_sock,SOL_SOCKET,SO_RCVBUF,&

bufsize,&

optlen);

//printf("

defaultsend/recvbufsize:

bufsize);

while

(1){

fd_setreadset;

FD_ZERO(&

readset);

intmaxfd=0;

FD_SET(server_socks[i],&

if(server_socks[i]&

maxfd){

maxfd=server_socks[i];

intret=select(maxfd+1,&

readset,NULL,NULL,NULL);

if(ret&

0){

if(errno==EINTR){

continue;

}else{

selecterror!

%s\n"

strerror(errno));

exit(0);

if(!

FD_ISSET(server_socks[i],&

readset)){

socklen_taddrlen=sizeof(addr);

intsock=accept(server_socks[i],(structsockaddr*)&

addr,&

addrlen);

if(sock==-1){

connections++;

connections:

%d,fd:

connections,sock);

return0;

sock_err:

error:

}

注意,服务器监听了10个端口,这是为了测试方便.因为只有一台客户端测试机,最多只能跟同一个IP端口创建30000多个连接,所以服务器监听了10个端口,这样一台测试机就可以和服务器之间创建30万个连接了.

客户端

=2){

Usage:

%sipport\n"

argv[0]);

constchar*ip=argv[1];

intbase_port=atoi(argv[2]);

chartmp_data[10];

intindex=0;

if(++index&

=10){

index=0;

intport=base_port+index;

connectto%s:

%d\n"

ip,port);

intsock;

if((sock=socket(AF_INET,SOCK_STREAM,0))==-1){

if(connect(sock,(structsockaddr*)&

if(connections%10000==9999){

pressEntertocontinue:

"

);

getchar();

usleep(1*1000);

/*

bufsize=5000;

setsockopt(serv_sock,SOL_SOCKET,SO_SNDBUF,&

bufsize,sizeof(bufsize));

setsockopt(serv_sock,SOL_SOCKET,SO_RCVBUF,&

*/

我测试10万个连接,这些连接是空闲的,什么数据也不发送也不接收.这时,进程只占用了不到1MB的内存.但是,通过程序退出前后的free命令对比,发现操作系统用了200M(大致)内存来维护这10万个连接!

如果是百万连接的话,操作系统本身就要占用2GB的内存!

也即2KB每连接.

可以修改

/proc/sys/net/ipv4/tcp_wmem

/proc/sys/net/ipv4/tcp_rmem

来控制TCP连接的发送和接收缓冲的大小(多谢@egmkang).

3.应用程序维持百万连接需要多少内存?

通过上面的测试代码,可以发现,应用程序维持百万个空闲的连接,只会占用操作系统的内存,通过ps命令查看可知,应用程序本身几乎不占用内存.

4.百万连接的吞吐量是否超过了网络限制?

假设百万连接中有20%是活跃的,每个连接每秒传输1KB的数据,那么需要的网络带宽是0.2Mx1KB/sx8=1.6Gbps,要求服务器至少是万兆网卡(10Gbps).

总结

Linux系统需要修改内核参数和系统配置,才能支持C1000K.C1000K的应用要求服务器至少需要2GB内存,如果应用本身还需要内存,这个要求应该是至少10GB内存.同时,网卡应该至少是万兆网卡.

当然,这仅仅是理论分析,实际的应用需要更多的内存和CPU资源来处理业务数据.

参考:

*http:

//www.cyberciti.biz/faq/linux-increase-the-maximum-number-of-open-files/

*

Relatedposts:

要记得清除sockaddr_in

构建C1000K的服务器

(2)–实现百万连接的comet服务器

数据传输中的停止等待机制的实现

Libevent2HTTP客户端示例

有趣的main函数参数

实现百万连接的comet服务器

这是关于C1000K序列文章的第二篇,在前一篇文章构建C1000K的服务器

(1)–基础中,介绍了支持C1000K的Linux系统的内核参数调整和系统设置.在本篇文章中,将对一个真正的应用服务器做C1000K测试.Comet服务器是一类逻辑相对简单,需要高并发连接的服务器.Comet在网站系统中的应用非常广泛,可以见这篇日志的介绍:

协议处理要开发一个支持百万并发连接的Comet服务器,我选择C/C++语言,当然还有其它的选择如Erlang,Java等.对于一个只支持long-pollingComet服务器,首先要具备解析HTTP协议的能力,我选择libevent来处理HTTP协议.通道和订阅者管理服务器在启动的时候,就预先分配了100万个通道对象的空间,但订阅者对象是按需分配的,通过内存池方式.100万个通道对象和程序的其它数据占用了24MB的内存.Benchmark启动icomet服务器:

./icomet

服务器监听了100个端口,是为了测试方便,原因见前一篇文章的分析:

构建C1000K的服务器

(1)–基础.然后启动benchmark客户端:

./tools/benchmark127.0.0.18100

benchmark程序每创建十万个连接,就会暂停,按回车后继续.通过top/ps查看icomet进程的内存占用.最终,得出如下数据.连接数进程VIRT进程RES039m24m100000302m288m200000579m565m5000001441m1427m10000002734m2720m

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 幼儿教育 > 育儿理论经验

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1