webbench簡介html
webbench由C語言寫成的用於網站壓力測試的一個很是簡單的工具,它最多能夠模擬30000個併發鏈接去進行測試。web
webbench的安裝和使用能夠自行百度,也能夠過下這篇文章。併發
webbench執行流程dom
命令行解析 --> 構建HTTP請求包 --> 建立指定數量的工做進程 --> 每一個工做進程對測試網站在測試時間內持續發送請求/接收響應socket
具體分析函數
1. 命令行解析。工具
這裏主要用到了getopt庫。getopt庫是C中經常使用的命令行解析庫,具備以下一些經常使用的全局變量、結構體以及函數。測試
/* 經常使用全局變量 */ extern char* optarg; // 指向獲取的option extern int optind; // 已經解析過的option的個數 extern int opterr; // 錯誤碼 extern int optopt;
/* 結構體:解析option時主要的結構體,用以指明有哪些指定options */ struct option { const char* name; int has_arg; int* flag; int val; }; /* has_arg的幾個宏 */ #define no_argument 0 #define require_argument 1 #define optional_argument 2
/* 經常使用的幾個函數 */ int getopt(); int getopt_long(int __argc, char* const* __argv, const char* __shortopts, const struct option* __longopts, int* __longind); int getopt_long_only(int __argc, char* const* __argv, const char* __shortopts, const struct option* __longopts, int* __longind);
2. 構建HTTP請求包。網站
代碼調用了build_request函數對HTTP請求包進行了構建。常見的HTTP請求包構建規則:ui
請求方法 URL 協議版本 \r\n
頭部字段名: 值 \r\n
....
頭部字段名: 值 \r\n
\r\n
\r\n
請求數據
請求方法:GET, POST, HEAD, PUT, DELETE, TRACE, CONNECT, OPTIONS
協議版本:HTTP/1.0 HTTP/1.1
頭部: User-agent, Host, Pragma, Connection等等
3. 使用fork建立指定數量的工做進程,用pipe讓主進程和工做進程創建通訊,以便於主進程收集子進程的測試信息。
/* 使用fork建立多進程代碼片斷 */ static int bench(void) { ... for (i = 0; i < clients; i++) { pid = fork(); if (pid <= 0) // 若是是子進程或者fork失敗了,退出這個循環 { sleep(1); break; } } ... }
/* fork 函數聲明 */ #include <unistd.h> #include <sys/types.h> pid_t fork(void); // pid_t 在 sys/types.h 中定義 /* pipe 函數聲明 */ #include <unistd.h> int pipe(int pipefd[2]); /* fdopen 函數聲明 */ #include <stdio.h> FILE *fdopen(int fd, const char *mode); // 打開 pipe 文件
4. 每一個進程模擬一個客戶端,建立socket並鏈接測試web,用alarm定時測試時長,在這個時間段裏,客戶端持續向web請求並接收響應。
這裏有幾點要注意:
a) 在客戶端的socket須要兩步完成對web的鏈接:建立一個socket(使用socket()函數);鏈接web(使用connect()函數)。
b) alarm定時時長,輸入的參數只能是秒數。當定時時間到了的時候,系統會發送一個SIGALRM信號給alarm所在的進程,因此在調用alarm以前,須要註冊一個信號函數sigaction或signal(代碼中使用了sigaction),將SIGALRM與回調函數綁定,當系統發送SIGALRM,會調用相應的回調函數(代碼中使用了alarm_handler)進行處理。
上面幾個函數的聲明以下
/* socket, connect 函數聲明 */ #include <sys/types.h> #include <sys/socket.h> int socket(int domain, int type, int protocol); int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen); /* alarm 函數聲明 */ #include <unistd.h> unsigned int alarm(unsigned int seconds); /* sigaction 函數聲明 */ #include <signal.h> int sigaction(int signum, const struct sigaction *act, struct sigation *oldact); struct sigaction { void (*sa_handler) (int); void (*sa_sigaction) (int, siginfo_t*, void*); sigset_t sa_mask; int sa_flag; void (*sa_restorer) (void); };
完!
2018-03-21 23:39:46