webbench簡介 webbench由C語言寫成的用於網站壓力測試的一個非常簡單的工具,它最多可以模擬30000個併發連接去進行測試。 webbench的安裝和使用可以自行百度,也可以過下這篇文章。 webbench執行流程 命令行解析 --> 構建HTTP請求包 --> 創建指定數量的工作進程 ...
webbench簡介
webbench由C語言寫成的用於網站壓力測試的一個非常簡單的工具,它最多可以模擬30000個併發連接去進行測試。
webbench的安裝和使用可以自行百度,也可以過下這篇文章。
webbench執行流程
命令行解析 --> 構建HTTP請求包 --> 創建指定數量的工作進程 --> 每個工作進程對測試網站在測試時間內持續發送請求/接收響應
具體分析
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請求包構建規則:
請求方法 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