压力测试工具Webbench源码分析

原理

webbench首先fork出多个子进程,每个子进程都循环做web访问测试。子进程把访问的结果通过pipe告诉父进程,父进程做最终的统计结果。

项目地址:
http://home.tiscali.cz/~cz210552/webbench.html

程序结构

主函数:

main函数解析参数,调用bench();

bench():

  1. 检查目标服务器是否可用

    i = Socket(proxyhost==NULL?host:proxyhost,proxyport);

  2. 创建pipe;(pipe声明:mypipe[2];)若成功返回0,否则返回-1。其中pipe[0]是读管道,pipe[1]是写管道。参考网址

  3. 开辟子进程
    for(i=0;i<clients;i++)
    {
    pid=fork();
    //…
    }
    关于fork()函数参考这里,子进程返回0,父进程返回子进程标记,否则返回0.

  4. 如果是子进程,调用benchcore(host/proxyhost,proxyport,request)。将数据speed,failed,bytes的结果写入pipe。f=fdopen(mypipe[1],"w");fdopen取一个现存的文件描述符,并使一个标准的I / O流与该描述符相结合,转换成功时返回指向该流的文件指针。失败则返回NULL,并把错误代码存在errno中.
    fdopen参考这里

  5. 如果是父进程,循环从文件中读取数据,直到只剩一个进程为止。统计并输出最终结果。这里用到一个函数setvbuf,这个函数是设置缓冲区的,这里用_INOBF是无缓冲区,直接从流数据中读取。参考

benchcore():

  1. 设置计时器时间为benchtime,利用sigaction.
  2. 连接s=soket(host,port);
  3. write(s,req,rlen)写入请求。
  4. shutdown(s,1)关闭写请求。
  5. 如果force==0即不用等待服务器返回,读取socket中所有的数据i=read(s,buf,1500)。
  6. close(s)

alarm_handler():
计时器超时函数,设置timerexpired=1;

socket函数源码

int Socket(const char *host, int clientPort)
{
    int sock;
    unsigned long inaddr;
    struct sockaddr_in ad;
    struct hostent *hp;
    
    memset(&ad, 0, sizeof(ad));
    ad.sin_family = AF_INET;

    inaddr = inet_addr(host);
    if (inaddr != INADDR_NONE)
        memcpy(&ad.sin_addr, &inaddr, sizeof(inaddr));
    else
    {
        hp = gethostbyname(host);
        if (hp == NULL)
            return -1;
        memcpy(&ad.sin_addr, hp->h_addr, hp->h_length);
    }
    ad.sin_port = htons(clientPort);
    
    sock = socket(AF_INET, SOCK_STREAM, 0);
    if (sock < 0)
        return sock;
    if (connect(sock, (struct sockaddr *)&ad, sizeof(ad)) < 0)
        return -1;
    return sock;
}

Webbench的安装和使用

参考

[root@node1 ~]# yum install -y gcc ctags
[root@node1 ~]# wget http://www.ha97.com/code/webbench-1.5.tar.gz
[root@node1 ~]# tar -xvf  webbench-1.5.tar.gz
[root@node1 data]# cd webbench-1.5
[root@node1 webbench-1.5]# make && make install    ##这一步可能遇到如下错误,手动创建目录即可
cc -Wall -ggdb -W -O   -c -o webbench.o webbench.c
webbench.c: In function 鈥榓larm_handler鈥

                                           webbench.c:77: warning: unused parameter 鈥榮ignal鈥
cc -Wall -ggdb -W -O  -o webbench webbench.o  
ctags *.c
install -s webbench /usr/local/bin
install -m 644 webbench.1 /usr/local/man/man1
install: cannot create regular file `/usr/local/man/man1': No such file or directory
make: *** [install] Error 1
[root@node1 webbench-1.5]# mkdir /usr/local/man
[root@node1 webbench-1.5]# mkdir /usr/local/man/man1
[root@node1 webbench-1.5]# make &&make install
make: Nothing to be done for `all'.
install -s webbench /usr/local/bin
install -m 644 webbench.1 /usr/local/man/man1
install -d /usr/local/share/doc/webbench
install -m 644 debian/copyright /usr/local/share/doc/webbench
install -m 644 debian/changelog /usr/local/share/doc/webbench

usage()

[root@node1 data]# webbench --help
webbench [option]... URL
  -f|--force               Don't wait for reply from server.
  -r|--reload              Send reload request - Pragma: no-cache.
  -t|--time <sec>          Run benchmark for <sec> seconds. Default 30.
  -p|--proxy <server:port> Use proxy server for request.
  -c|--clients <n>         Run <n> HTTP clients at once. Default one.
  -9|--http09              Use HTTP/0.9 style requests.
  -1|--http10              Use HTTP/1.0 protocol.
  -2|--http11              Use HTTP/1.1 protocol.
  --get                    Use GET request method.
  --head                   Use HEAD request method.
  --options                Use OPTIONS request method.
  --trace                  Use TRACE request method.
  -?|-h|--help             This information.
  -V|--version             Display program version.

执行命令:webbench -c 10 http://www.baidu.com
命令就是用10个客户端并发百度网站30秒,但是在执行的命令报错了:Invalid URL syntax - hostname don't ends with '/'。解决办法就是在url后加个“/”

执行结果反馈内容:

[root@node1 data]# webbench -c 10 -t 30 http://www.baidu.com/
Webbench - Simple Web Benchmark 1.5
Copyright (c) Radim Kolar 1997-2004, GPL Open Source Software.

Benchmarking: GET http://www.baidu.com/
10 clients, running 30 sec.

Speed=2254 pages/min, 4188293 bytes/sec.
Requests: 1110 susceed, 17 failed.

其他一些压测工具:
http_load
apache bench
seige
wrk

测评的网址:参考1
参考2