Chinaunix首页 | 论坛 | 博客
  • 博客访问: 5758224
  • 博文数量: 675
  • 博客积分: 20301
  • 博客等级: 上将
  • 技术积分: 7671
  • 用 户 组: 普通用户
  • 注册时间: 2005-12-31 16:15
文章分类

全部博文(675)

文章存档

2012年(1)

2011年(20)

2010年(14)

2009年(63)

2008年(118)

2007年(141)

2006年(318)

分类: C/C++

2010-02-02 18:02:42

在网络应用开发过程中,经常需要对服务器程序进行压力测试,从而得到服务器的性能指标,或者是暴露程序的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) |
给主人留下些什么吧!~~