在网络应用开发过程中,经常需要对服务器程序进行压力测试,从而得到服务器的性能指标,或者是暴露程序的bug。在最近的项目中,我们也实现了一个业务相关的压力测试工具,专门用来测试我们的服务器代码。
大家所熟知的压力测试工具,比如http压力测试工具,ab(apache benchmark),zb(zeus benchmark),httperf等。这些压力测试工具的实现,基本上分为两种:
1. 采用原始套接字,比如httperf。
2. 采用非阻塞socket+I/O多路复用,比如ab,zb。ab代码依赖于apr(
Apache Portable Runtime),zb代码使用select,代码简洁,如果是要看代码结构还是推荐zb;-)
注意:ab和zb的代码都在apache2-utils包中参考ab的代码,我抽取出一个基于I/O多路复用的压力测试工具的框架:
main()->test()->start_connect()
---------------------------------------------------------
test:
for(i=0; i
{
start_connect(conns[i]);
}
while(1)
{
n=poll()
for(i=0; i
{
if(events[i].event == IN)
read_connection()
if(events[i].event == ERROR)
{
close_connect()
start_connect()
}
if(events[i].event == OUT)
if( conns[i].state == CONNECTING)
{
POLL_DEL(OUT,fd)
conns[i].state = CONNECTED;
write_request();
}
else
write_request();
}
}
|
--------------------------------------------------------
start_connection:
start_connect(conn* _conn)
{
socket()
setnonblock()
if( connect() == -1)
if( errno == EINPROCESS )
{
_conn->state = CONNECTING;
POLL_ADD(OUT, fd)
}
else
{
close_connection()
}
_conn->state = CONNECTED;
} |
---------------------------------------------------------
write_request:socket创建之后的第一个报文
write_request(conn *_conn)
{
while(total_send < n_write)
{
n = send() ;
if(n == -1 && errno != EAGAIN)
return close_connection()
total_send += n;
}
POLL_ADD(fd,IN);
} |
---------------------------------------------------------
read_connection:
read_connection()
{
recv();
process();
write_conntent(); //write_request()
} |
---------------------------------------------------------
注意:通常压力测试工具需要制定并发数,在连接断开后,应该再次连接,这样来保证连接数为设置值。这样就需要每次close_connection之后要马上调用start_connection(),保证连接数不变。
阅读(3010) | 评论(0) | 转发(0) |