




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、负载均衡器软件开发报告院系:班级:成员:目录1,可行性分析报告11.1 项目背景11.2 产品分析11.3 结论意见22 .项目开发计划22.1 总体功能要求22.2 软件开发平台要求22.3 软件项目的开发实力过程管理要求23 .软件开发23.1 软件的需求分析33.3 软件的详细设计43.4 软件的编码53.5 软件的测试313.5.1 测试计划313.5.2 软件测试314 .项目开发总结报告321 .可行性分析报告1.1 项目背景面对庞大的数据流量,面对集中性的访问,是不是觉得网络服务器岌岌可危呢?不用怕,负载均衡器就能帮你缓解这个问题。负载均衡器通过虚拟IP地址方法,解决了轮流排程所
2、面临的许多问题。使用了负载均衡器集群系统,在外部看来,像是具有一个IP地址的单一服务器一样,当然,这个IP地址是虚拟的,它映射了集群中的每一台机器的地址。所以,在某种程度上,负载均衡器是将整个集群的IP地址报漏给外部网络。当请求到达负载均衡器时,它会重写该请求的头文件,并将之指定到集群中的机器上。如果某台机器被从集群中移除了,请求不会别发往已经不存在的服务器上,因为所有的机器表面上都具有同一个IP地址,即使集群中的某个节点被移除了,该地址也不会发生变化。而且,internet上缓存的DN舔目也不再是问题了。当返回一个应答时,客户端看到的只是从负载均衡器上所返回的结果。也就是说,客户端操作的对象
3、是负载均衡器,对于其更后端的操作,对客户端来讲,是完全透明的。1.2 产品分析服务器一致性负载均衡器读取客户端发出的每一个请求中所包含的cookies或url解释。基于所读出的这些信息,负载均衡器就可以重写报头并将请求发往集群中合适的节点上,该节点维护着相应客户端请求的会话信息。在HTTP®信中,负载均衡器可以提供服务器一致性,但并不是通过一个安全的途径(例如:HTTPS来提供这种服务。当消息被加密后(SSD,负载均衡器就不能读出隐藏在其中的会话信息。通过故障恢复机制获得高可靠性故障恢复发生在当集群中某个节点不能处理请求,需将请求重新导向到其他节点时。主要有两种故障恢复:请求级故障恢
4、复。当集群中的一个节点不能处理请求时(通常是由于down机),请求被发送到其他节点。当然,在导向到其他节点的同时,保存在原节点上的会话信息将会丢失。透明会话故障恢复。当一个引用失败后,负载均衡器会将之发送到集群中其他的节点上,以完成操作,这一点对用户来说是透明的。由于透明会话故障恢复需要节点具备相应的操作信息,因此为了实现该功能,集群中的所有节点必须具有公共存储区域或通用数据库,存储会话信息数据,以提供每个节点在进行单独进程会话故障恢复时所需要的操作信息。既然所有的Wetg用请求都必须经过负载均衡系统,那么系统就可以确定活动会话的数量,在任何实例访问中的活动会话的数目,应答的次数,高峰负载次数
5、,以及在高峰期和低谷期的会话的数目,还有其他更多的。所有的这些统计信息都可以被很好的用来调整整个系统的性能。1.3 结论意见虽然此项目存在一定的技术难度和风险,但我们对项目要达到的目标十分清楚,对所要开发系统将要实现的功能也非常了解。而且有一些成品作为参考,并且在项目的实施过程中我们能够获得帮助,我认为只要我们能够认真思考、仔细规划、明确分工,我们可以承担此项目的开发。2 .项目开发计划2.1 总体功能要求1 .扩展网络设备和服务器的带宽2 .增加吞吐量3 .加强网络数据处理能力4 .提高网络的灵活性和可用性2.2 软件开发平台要求Visualc+6.0SQLServer2008C+Build
6、er网络架构:完全支持TCP/IP协议2.3 软件项目的开发实施过程管理要求3 .软件开发3.1 软件的需求分析1 .DNS负载均衡最早的负载均衡技术是通过DNSE实现的,在DNS为多个地址配置同一个名字,因而查询这个名字的客户机将得到其中一个地址,从而使得不同的客户访问不同的服务器,达到负载均衡的目的。DNS负载均衡是一种简单而有效的方法,但是它不能区分服务器的差异,也不能反映服务器的当前运行状态。2 .代理服务器负载均衡使用代理服务器,可以将请求转发给内部的服务器,使用这种加速模式显然可以提升静态网页的访问速度。然而,也可以考虑这样一种技术,使用代理服务器将请求均匀转发给多台服务器,从而达
7、到负载均衡的目的。3 .地址转换网关负载均衡支持负载均衡的地址转换网关,可以将一个外部IP地址映射为多个内部IP地址,对每次TCP1接请求动态使用其中一个内部地址,达到负载均衡的目的。4 .协议内部支持负载均衡除了这三种负载均衡方式之外,有的协议内部支持与负载均衡相关的功能,例如HTTPB议中的重定向能力等,HTTPJ!行于TCP连接的最高层。5 .NAT负载土衡NAT简单地说就是将一个IP地址转换为另一个IP地址,一般用于未经注册的内部地址与合法的、已获注册的InternetIP地址间进行转换。适用于解决InternetIP地址紧张、不想让网络外部知道内部网络结构等的场合下。6 .反向代理负
8、载均衡普通代理方式是代理内部网络用户访问internet上服务器的连接请求,客户端必须指定代理服务器,并将本来要直接发送到internet上服务器的连接请求发送给代理服务器处理。反向代理(ReverseProxy)方式是指以代理服务器来接受internet上的连接请求,然后将请求转发给内部网络上的服务器,并将从服务器上得到的结果返回给internet上请求连接的客户端,此时代理服务器对外就表现为一个服务器。反向代理负载均衡技术是把将来自internet上的连接请求以反向代理的方式动态地转发给内部网络上的多台服务器进行处理,从而达到负载均衡的目的。7 .混合型负载均衡在有些大型网络,由于多个服务
9、器群内硬件设备、各自的规模、提供的服务等的差异,可以考虑给每个服务器群采用最合适的负载均衡方式,然后又在这多个服务器群间再一次负载均衡或群集起来以一个整体向外界提供服务(即把这多个服务器群当做一个新的服务器群),从而达到最佳的性能。将这种方式称之为混合型负载均衡。此种方式有时也用于单台均衡设备的性能不能满足大量连接请求的情况下。3.2 软件的概要设计软件负载均衡解决方案是指在一台或多台服务器相应的操作系统上安装一个或多个附加软件来实现负载均衡,DNSLoadBalanceCheckPointFirewall-1ConnectControl等,它的优点是基于特定环境,配置简单,使用灵活,成本低廉
10、,可以满足一般的负载均衡需求。硬件负载均衡解决方案是直接在服务器和外部网络间安装负载均衡设备,这种设备通常称之为负载均衡器,由于专门的设备完成专门的任务,独立于操作系统,整体性能得到大量提高,加上多样化的负载均衡策略,智能化的流量管理,可达到最佳的负载均衡需求。一般而言,硬件负载均衡在功能、性能上优于软件方式,不过成本昂贵。本地负载均衡能有效地解决数据流量过大、网络负荷过重的问题,并且不需花费昂贵开支购置性能卓越的服务器,充分利用现有设备,避免服务器单点故障造成数据流量的损失。具有灵活多样的均衡策略把数据流量合理地分配给服务器群内的服务器共同负担。即使是再给现有服务器扩充升级,也只是简单地增加
11、一个新的服务器到服务群中,而不需改变现有网络结构、停止现有的服务。全局负载均衡主要用于在一个多区域拥有自己服务器的站点,为了使全球用户只以一个IP地址或域名就能访问到离自己最近的服务器,从而获得最快的访问速度,也可用于子公司分散站点分布广的大公司通过企业内部互联网来达到资源统一合理分配的目的。3.3 软件的详细设计1 .轮转法:轮转算法是所有调度算法中最简单也最容易实现的一种方法。在一个任务队列里,队列的每个成员(节点)都具有相同的地位,轮转法简单的在这组成员中顺序轮转选择。在负载平衡环境中,均衡器将新的请求轮流发给节点队列中的下一节点,如此连续、周而复始,每个集群的节点都在相等的地位下被轮流
12、选择。这个算法在DNS®名轮询中被广泛使用。轮转法的活动是可预知的,每个节点被选择的机会是1/N,因此很容易计算出节点的负载分布。轮转法典型的适用于集群中所有节点的处理能力和性能均相同的情况,在实际应用中,一般将它与其他简单方法联合使用时比较有效。2 .散列法:散列法也叫哈希法(HASH,通过单射不可逆的HASPS数,按照某种规则将网络请求发往集群节点。哈希法在其他几类平衡算法不是很有效时会显示出特别的威力。例如,在前面提到的UD%话的情况下,由于轮转法和其他几类基于连接信息的算法,无法识别出会话的起止标记,会引起应用混乱。而采取基于数据包源地址的哈希映射可以在一定程度上解决这个问题
13、:将具有相同源地址的数据包发给同一服务器节点,这使得基于高层会话的事务可以以适当的方式运行。相对称的是,基于目的地址的哈希调度算法可以用在WebCache集群中,指向同一个目标站点的访问请求都被负载平衡器发送到同一个Cache服务节点上,以避免页面缺失而带来的更新Cache问题。3 .最少连接法:在最少连接法中,平衡器纪录目前所有活跃连接,把下一个新的请求发给当前含有最少连接数的节点。这种算法针对TCR!接进行,但由于不同应用对系统资源的消耗可能差异很大,而连接数无法反映出真实的应用负载,因此在使用重型Web服务器作为集群节点服务时(例如Apache服务器),该算法在平衡负载的效果上要打个折扣
14、。为了减少这个不利的影响,可以对每个节点设置最大的连接数上限(通过阈值设定体现)。4 .最低缺失法:在最低缺失法中,平衡器长期纪录到各节点的请求情况,把下个请求发给历史上处理请求最少的节点。与最少连接法不同的是,最低缺失记录过去的连接数而不是当前的连接数。5 .最快响应法:平衡器记录自身到每一个集群节点的网络响应时间,并将下一个到达的连接请求分配给响应时间最短的节点,这种方法要求使用ICMP包或基于UDPfe的专用技术来主动探测各节点。在大多数基于LAN的集群中,最快响应算法工作的并不是很好,因为LAN中的ICMPfe基本上都在10ms内完成回应,体现不出节点之间的差异;如果在WAN上进行平衡
15、的话,响应时间对于用户就近选择服务器而言还是具有现实意义的;而且集群的拓扑越分散这种方法越能体现出效果来。这种方法是高级平衡基于拓扑结构重定向用到的主要方法。6 .加权法:加权方法只能与其他方法合用,是它们的一个很好的补充。加权算法根据节点的优先级或当前的负载状况(即权值)来构成负载平衡的多优先级队列,队列中的每个等待处理的连接都具有相同处理等级,这样在同一个队列里可以按照前面的轮转法或者最少连接法进行均衡,而队列之间按照优先级的先后顺序进行均衡处理。在这里权值是基于各节点能力的一个估计值。3.4 软件的编码#include<exception>#include<errno.
16、h>#include<string.h>#include"conn.h"#include"log.h"#include"fdwrapper.h"conn二conn()m_srvfd=-1;m_clt_buf=newcharBUF_SIZE;if(!m_clt_buf)throwstd:exception();m_srv_buf=newcharBUF_SIZE;if(!m_srv_buf)throwstd:exception();reset();conn二conn()deletem_clt_buf;deletem_sr
17、v_buf;voidconn:init_clt(intsockfd,constsockaddr_in&client_addr)m_cltfd=sockfd;m_clt_address=client_addr;voidconn:init_srv(intsockfd,constsockaddr_in&server_addr)m_srvfd=sockfd;m_srv_address=server_addr;voidconn:reset()m_clt_read_idx=0;m_clt_write_idx=0;m_srv_read_idx=0;m_srv_write_idx=0;m_sr
18、v_closed=false;m_cltfd=-1;memset(m_clt_buf,''0',BUF_SIZE);memset(m_srv_buf,'0',BUF_SIZE);RET_CODEconn:read_clt()(intbytes_read=0;while(true)(if(m_clt_read_idx>=BUF_SIZE)(log(LOG_ERF_FILE_,_LINE_,"%s","theclientreadbufferisfull,letserverwrite");returnBUFFER_
19、FULL;bytes_read=recv(m_cltfd,m_clt_buf+m_clt_read_idx,BUF_SIZE-m_clt_read_idx,0);if(bytes_read=-1)(if(errno=EAGAIN|errno=EWOULDBLOCK)(break;returnIOERR;elseif(bytes_read=0)(returnCLOSED;m_clt_read_idx+=bytes_read;return(m_clt_read_idx-m_clt_write_idx)>0)?OK:NOTHING;RET_CODEconn:read_srv()(intbyte
20、s_read=0;while(true)(if(m_srv_read_idx>=BUF_SIZE)(log(LOG_ERF_FILE_,_LINE_,"%s","theserverreadbufferisfull,letclientwrite");returnBUFFER_FULL;bytes_read=recv(m_srvfd,m_srv_buf+m_srv_read_idx,BUF_SIZE-m_srv_read_idx,0);if(bytes_read=-1)(if(errno=EAGAIN|errno=EWOULDBLOCK)(break;
21、returnIOERR;elseif(bytes_read=0)(log(LOG_ERR,_FILE_,_LINE_,"%s","theservershouldnotclosethepersistconnection");returnCLOSED;m_srv_read_idx+=bytes_read;return(m_srv_read_idx-m_srv_write_idx)>0)?OK:NOTHING;RET_CODEconn:write_srv()(intbytes_write=0;while(true)(if(m_clt_read_idx&l
22、t;=m_clt_write_idx)(m_clt_read_idx=0;m_clt_write_idx=0;returnBUFFER_EMPTY;bytes_write=send(m_srvfd,m_clt_buf+m_clt_write_idx,m_clt_read_idx-m_clt_write_idx,0);if(bytes_write=-1)if(errno=EAGAIN|errno=EWOULDBLOCK)returnTRY_AGAIN;)log(LOG_ERR,_FILE_,_LINE_,"writeserversocketfailed,%s",strerro
23、r(errno);returnIOERR;)elseif(bytes_write=0)returnCLOSED;)m_clt_write_idx+=bytes_write;)RET_CODEconn:write_clt()intbytes_write=0;while(true)if(m_srv_read_idx<=m_srv_write_idx)m_srv_read_idx=0;m_srv_write_idx=0;returnBUFFER_EMPTY;)bytes_write=send(m_cltfd,m_srv_buf+m_srv_write_idx,m_srv_read_idx-m_
24、srv_write_idx,0);if(bytes_write=-1)(if(errno=EAGAIN|errno=EWOULDBLOCK)(returnTRY_AGAIN;log(LOG_ERR,_FILE_,_LINE_,"writeclientsocketfailed,%s",strerror(errno);returnIOERR;elseif(bytes_write=0)(returnCLOSED;m_srv_write_idx+=bytes_write;#ifndefFDWRAPPER_H#defineFDWRAPPER_H#include<unistd.h
25、>#include<fcntl.h>#include<sys/epoll.h>intsetnonblocking(intfd)(intold_option=fcntl(fd,F_GETFL);intnew_option=old_option|O_NONBLOCK;fcntl(fd,F_SETFL,new_option);returnold_option;voidadd_read_fd(intepollfd,intfd)(epoll_eventevent;event.data.fd=fd;event.events=EPOLLIN|EPOLLET;epoll_ctl(
26、epollfd,EPOLL_CTL_ADD,fd,&event);setnonblocking(fd);voidadd_write_fd(intepollfd,intfd)epoll_eventevent;event.data.fd=fd;event.events=EPOLLOUT|EPOLLET;epoll_ctl(epollfd,EPOLL_CTL_ADD,fd,&event);setnonblocking(fd);voidclosefd(intepollfd,intfd)epoll_ctl(epollfd,EPOLL_CTL_DEL,fd,0);close(fd);voi
27、dremovefd(intepollfd,intfd)epoll_ctl(epollfd,EPOLL_CTL_DEL,fd,0);voidmodfd(intepollfd,intfd,intev)epoll_eventevent;event.data.fd=fd;event.events=ev|EPOLLET;epoll_ctl(epollfd,EPOLL_CTL_MOD,fd,&event);#endif#include<stdio.h>#include<time.h>#include<string.h>#include"log.h&qu
28、ot;staticintlevel=LOG_INFO;staticintLOG_BUFFER_SIZE=2048;staticconstchar*loglevels="emerge!","alert!","critical!","error!","warn!","notice:","info:","debug:");voidset_loglevel(intlog_level)level=log_level;)voidlog(intlog
29、_level,constchar*file_name,intline_num,constchar*format,.)if(log_level>level)return;)time_ttmp=time(NULL);structtm*cur_time=localtime(&tmp);if(!cur_time)return;)chararg_bufferLOG_BUFFER_SIZE;memset(arg_buffer,''0',LOG_BUFFER_SIZE);strftime(arg_buffer,LOG_BUFFER_SIZE1,"%x%X”,c
30、ur_time);printf("%s",arg_buffer);printf("%s:%04d",file_name,line_num);printf("%s",loglevelslog_level-LOG_EMERG);va_listarg_list;va_start(arg_list,format);memset(arg_buffer,'0',LOG_BUFFER_SIZE);vsnprintf(arg_buffer,LOG_BUFFER_SIZE-1,format,arg_list);printf("
31、%sn",arg_buffer);fflush(stdout);va_end(arg_list);)#include<sys/types.h>#include<sys/socket.h>#include<netinet/in.h>#include<arpa/inet.h>#include<assert.h>#include<stdio.h>#include<unistd.h>#include<errno.h>#include<string.h>#include<fcntl
32、.h>#include<stdlib.h>#include<sys/epoll.h>#include<signal.h>#include<sys/wait.h>#include<sys/stat.h>#include<vector>#include"log.h"#include"conn.h"#include"mgr.h"#include"processpool.h"usingstd:vector;staticconstchar*vers
33、ion="1.0"staticvoidusage(constchar*prog)-flog(LOG_INFO,_FILE_,_LINE_,"usage:%s卜h-vconfig_file”,prog);intmain(intargc,char*argv)charcfg_file1024;memset(cfg_file,''0',100);intoption;while(option=getopt(argc,argv,"f:xvh")!=-1)switch(option)case'x':set_loglev
34、el(LOG_DEBUG);break;case'v':(log(LOG_INFO,_FILE_,_LINE_,"%s%s",argv0,version);return0;case'h':(usage(basename(argv0);return0;case'f:(memcpy(cfg_file,optarg,strlen(optarg);break;case'?':(log(LOGERR,FILE,LINE,"un-recognizedoption%c",option);usage(basenam
35、e(argv0);return1;if(cfg_file0='0')(log(LOG_ERR,FILE,LINE,"%s","pleasespecifiytheconfigfile");return1;intcfg_fd=open(cfg_file,O_RDONLY);if(!cfg_fd)(log(LOG_ERR,_FILE_,_LINE_,"readconfigfilemeterror:%s”,strerror(errno);return1;structstatret_stat;if(fstat(cfg_fd,&re
36、t_stat)<0)(log(LOG_ERR,_FILE_,_LINE_,"readconfigfilemeterror:%s",strerror(errno);return1;char*buf=newcharret_stat.st_size+1;memset(buf,'0',ret_stat.st_size+1);ssize_tread_sz=read(cfg_fd,buf,ret_stat.st_size);if(read_sz<0)(log(LOG_ERR,_FILE_,_LINE_,"readconfigfilemeterror
37、:%s",strerror(errno);return1;vector<host>balance_srv;vector<host>logical_srv;hosttmp_host;memset(tmp_host.m_hostname,'0',1024);char*tmp_hostname;char*tmp_port;char*tmp_conncnt;boolopentag=false;char*tmp=buf;char*tmp2=NULL;char*tmp3=NULL;char*tmp4=NULL;while(tmp2=strpbrk(tmp,
38、"n")(*tmp2+='0'if(strstr(tmp,"<logical_host>")(if(opentag)(log(LOG_ERR,_FILE_,_LINE_,"%sH,"parseconfigfilefailed");return1;opentag=true;elseif(strstr(tmp,"</logical_host>")(if(!opentag)(log(LOG_ERR,_FILE_,_LINE_,"%s","pa
39、rseconfigfilefailed");return1;logical_srv.push_back(tmp_host);memset(tmp_host.m_hostname,'0',1024);opentag=false;elseif(tmp3=strstr(tmp,"<name>")(tmp_hostname=tmp3+6;tmp4=strstr(tmp_hostname,”</name>");if(!tmp4)(log(LOG_ERR,_FILE_,_LINE_,"%s","p
40、arseconfigfilefailed");return1;)*tmp4='0'memcpy(tmphost.mhostname,tmphostname,strlen(tmp_hostname);)elseif(tmp3=strstr(tmp,"<port>")tmp_port=tmp3+6;tmp4=strstr(tmp_port,"</port>");if(!tmp4)10g(LOG_ERR,_FILE_,_LINE_,"%s","parseconfigfilefail
41、ed");return1;)*tmp4='0'tmp_host.m_port=atoi(tmp_port);)elseif(tmp3=strstr(tmp,"<conns>")tmp_conncnt=tmp3+7;tmp4=strstr(tmp_conncnt,"</conns>");if(!tmp4)10g(LOG_ERR,_FILE_,_LINE_,"%s","parseconfigfilefailed");return1;)*tmp4='0't
42、mp_host.m_conncnt=atoi(tmp_conncnt);elseif(tmp3=strstr(tmp,"Listen")(tmp_hostname=tmp3+6;tmp4=strstr(tmp_hostname,":");if(!tmp4)(10g(LOG_ERR,_FILE_,_LINE_,"%s","parseconfigfilefailed");return1;*tmp4+='0'tmp_host.m_port=atoi(tmp4);memcpy(tmp_host.m_host
43、name,tmp3,strlen(tmp3);balance_srv.push_back(tmp_host);memset(tmp_host.m_hostname,'0',1024);tmp=tmp2;if(balance_srv.size()=0|logical_srv.size()=0)(log(LOGERR,FILE,LINE,"%s","parseconfigfilefailed");return1;constchar*ip=balance_srv0.m_hostname;intport=balance_srv0.m_port;i
44、ntlistenfd=socket(PF_INET,SOCK_STREAM,0);assert(listenfd>=0);intret=0;structsockaddr_inaddress;bzero(&address,sizeof(address);address.sin_family=AF_INET;inet_pton(AF_INET,ip,&address.sin_addr);address.sin_port=htons(port);ret=bind(listenfd,(structsockaddr*)&address,sizeof(address);ass
45、ert(ret!=-1);ret=listen(listenfd,5);assert(ret!=-1);/memset(cfg_host.m_hostname,''0',1024);memcpy(cfg_host.m_hostname,"",strlen("");/cfg_host.m_port=54321;cfg_host.m_conncnt=5;processpool<conn,host,mgr>*pool=processpool<conn,host,mgr>:cre
46、ate(listenfd,logical_srv.size();if(pool)pool->run(logical_srv);deletepool;close(listenfd);return0;#include<sys/types.h>#include<sys/socket.h>#include<netinet/in.h>#include<arpa/inet.h>#include<assert.h>#include<stdio.h>#include<unistd.h>#include<errno.
47、h>#include<string.h>#include<fcntl.h>#include<stdlib.h>#include<sys/epoll.h>#include<signal.h>#include<sys/wait.h>#include<sys/stat.h>#include<exception>#include"log.h"#include"mgr.h"usingstd二pair;intmgr二m_ep011fd=-1;intmgr二conn2
48、sMconstsockaddr_in&address)intsockfd=socket(PF_INET,SOCK_STREAM,0);if(sockfd<0)return-1;)&address,if(connect(sockfd,(structsockaddr*sizeof(address)!=0)close(sockfd);return-1;returnsockfd;mgr:mgr(intepollfd,consthost&srv):m_logic_srv(srv)(m_epollfd=epollfd;intret=0;structsockaddr_inadd
49、ress;bzero(&address,sizeof(address);address.sin_family=AF_INET;inet_pton(AF_INET,srv.m_hostname,&address.sin_addr);address.sin_port=htons(srv.m_port);log(LOG_INFO_FILE_,_LINE,"logcialsrvhostinfo:(%s,%d)”,srv.m_hostname,srv.m_port);for(inti=0;i<srv.m_conncnt;+i)(sleep(1);intsockfd=con
50、n2srv(address);if(sockfd<0)(log(LOGERR,FILE,LINE,"buildconnection%dfailed",i);)else(log(LOG_INFO,FILE,LINE,"buildconnection%dtoserversuccess",i);conn*tmp=NULL;try(tmp=newconn;)catch(.)(close(sockfd);continue;)tmp->init_srv(sockfd,address);m_conns.insert(pair<int,conn*>
51、;(sockfd,tmp);)mgr:mgr()()intmgr:get_used_conn_cnt()(returnm_used.size();)conn*mgr:pick_conn(intcltfd)(if(m_conns.empty()srv(log(LOG_ERR,_FILE,LINE,"%s","notenoughconnectionstoserver");returnNULL;)map<int,conn*>:iteratoriter=m_conns.begin();intsrvfd=iter->first;conn*tmp=
52、iter->second;if(!tmp)(log(LOGERR,FILE,LINE,"%s","emptyserverconnectionobject");returnNULL;m_conns.erase(iter);m_used.insert(pair<int,conn*>(cltfd,tmp);m_used.insert(pair<int,conn*>(srvfd,tmp);add_read_fd(m_epollfd,cltfd);add_read_fd(m_epollfd,srvfd);log(LOG_INFO,_F
53、ILE_,LINE,"bindclientsock%dwithserversock%d",cltfd,srvfd);returntmp;voidmgr:free_conn(conn*connection)(intcltfd=connection->m_cltfd;intsrvfd=connection->m_srvfd;closefd(m_epollfd,cltfd);closefd(m_epollfd,srvfd);m_used.erase(cltfd);m_used.erase(srvfd);connection->reset();m_freed.in
54、sert(pair<int,conn*>(srvfd,connection);voidmgr:recycle_conns()(if(m_freed.empty()(return;for(map<int,conn*>:iteratoriter=mfreed.begin();iter!=m_freed.end();iter+)sleep(1);intsrvfd=iter->first;conn*tmp=iter->second;srvfd=conn2sMtmp->m_srv_address);if(srvfd<0)log(LOG_ERR,_FILE_,_LINE_,"%s","fixconnectionfailed");elselog(LOG_INFO,_FILE_,_LINE_,"%s","fixconnectionsuccess");tmp->init_srv(srvfd,tmp->m_srv_address);m_conns.insert(pair<int,conn*&
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 跨境公共交通工具融资考核试卷
- 纺织品市场的市场竞争策略考核试卷
- 通信设备在智能停车场管理中的应用考核试卷
- 纱线市场趋势分析与预测考核试卷
- 无机酸在油墨工业中的应用考核试卷
- 私募股权投资文化娱乐产业投资考核试卷
- 花卉的种植与传统文化考核试卷
- 玉石行业人才培养与职业规划考核试卷
- 油料作物种植与农业科技创新驱动考核试卷
- 血液感染护理常规
- 【课件】图形的旋转+课件2024-2025学年华东师大版(2024)数学七年级下册+
- 赤峰市垃圾焚烧发电项目
- 2025年心理咨询师执业资格考试试题及答案
- 湖北省武汉市常青联合体2024-2025学年高一下学期期中考试历史试题(原卷版+解析版)
- 2024年蚌埠市龙子湖区产业发展有限公司招聘笔试真题
- 2025-2030中国萤石行业分析及供需形势与投资风险研究报告
- 2025-2030硅胶行业市场发展分析及趋势前景与投资战略研究报告
- (四调)武汉市2025届高中毕业生四月调研考试 数学试卷(含答案详解)
- 籍贯对照表完整版
- GB 20664-2006有色金属矿产品的天然放射性限值
- 西门子S7-200自动售货机课程设计(共16页)
评论
0/150
提交评论