修改Apache Benchmark原始碼實現請求資料隨機的壓力測試
Apache Benchmark(簡稱ab)是Apache附帶的一款開源的網站壓力測試工具,可以同時模擬大量併發請求,簡單易用。
在用ab對自己的網站進行壓力測試時發現:ab模擬的併發請求傳送的資料都是同一個,而我希望併發請求能夠傳送不同的資料。ab雖然支援從指定檔案中讀取需要post的資料,但不支援讀取多個檔案,所有併發請求傳送的都是同一個檔案中的資料。
ab是一款開放原始碼的壓力測試工具,因此可以通過修改原始碼來實現我希望的效果。
研究ab的原始碼發現,ab從檔案中讀出需要post的資料後,儲存在全域性字串變數postdata中。然後取postdata與準備好的http報文頭組裝成完整的http請求儲存在全域性字串變數request中。之後為每一個併發請求分別建立一個socket連線,對每個連線分別呼叫函式write_request(struct connection *c)傳送request。
因此可以通過修改write_request(struct connection *c)函式,在傳送request之前修改request的內容來實現期望的效果。
我的需求是這樣:
傳送的請求資料的格式為“&searchKey=ABCD”(不含引號),其中ABCD這段要求所有併發請求各自隨機生成,定長4位,由大寫英文字母構成。
具體的程式碼修改方法如下:
首先新增函式char *get_new_request(),該函式用於修改request得到一個新的request,函式體如下:
然後修改函式void write_request(struct connection *c),找到其中如下的一條語句:static char *get_new_request(){ char *buff = xmalloc(postlen + reqlen + 1); strcpy(buff, request); char *tmpdata = xmalloc(postlen); strcpy(tmpdata, postdata); for (int i = 0; i < 4; i++){ tmpdata[25 + i] = 'A' + rand() % 26; } memcpy(buff + reqlen, tmpdata, postlen); free(tmpdata); return buff; }
e = apr_socket_send(c->aprsock, request + c->rwrote, &l);
這條語句用於傳送request,將其修改如下:
char *newrequest = get_new_request();
e = apr_socket_send(c->aprsock, newrequest + c->rwrote, &l);
free(newrequest);
這樣就完成了程式碼的修改,儲存後就可以編譯執行了。以下是具體操作流程,包括相關檔案下載、修改程式碼、編譯安裝、執行等,若已熟悉此過程可直接跳過。
本過程在linux環境下完成,我使用的系統版本是redhat server6.3。
1、下載相關檔案
安裝apache之前必須先安裝apr、apr-util、pcre這三個工具,因此我們需要下載如下4個檔案:
下載httpd-2.4.16.tar.bz2 :地址
下載apr-1.5.2.tar.gz:地址
下載apr-util-1.5.4.tar.gz:地址
下載pcre-8.37.tar.gz:地址
下載後放到目錄/opt/(可自行指定)下。
2、修改原始碼
解壓檔案httpd-2.4.16.tar.bz2後,在httpd-2.4.16/support/目錄下可以找到檔案ab.c,這就是ab的原始碼檔案,按自己的需求對其進行修改即可,修改完成後將資料夾httpd-2.4.16重新打包為httpd-2.4.16.tar.bz2。
3、編譯安裝
1)解除安裝系統原有的Apache:
開啟終端,進入root。
執行如下命令:
rpm-e gnome-user-share
然後執行:
rpm -qa| grep httpd
回車後顯示如下資訊(版本號可能有所不同):
httpd-tools-2.2.15-15.el6_2.1.x86_64
httpd-2.2.15-15.el6_2.1.x86_64表示需要解除安裝這兩個軟體包,從下往上解除安裝。執行如下命令:
rpm-e httpd-2.2.15-15.el6_2.1.x86_64rpm-e httpd- tools-2.2.15-15.el6_2.1.x86_64
注:如果沒有先解除安裝gnome-user-share,則可能會遇到如下錯誤:
error: Failed dependencies:
httpd>= 2.2.0 is needed by (installed) gnome-user-share-2.28.2-3.el6.x86_642)安裝C++編譯器(若已安裝過,則跳過)
在linux的安裝盤中的Packages資料夾中找到檔案gcc-c++-4.4.6-4.el6.x86_64.rpm(版本號可能不同),雙擊即可安裝。
3)安裝apr
分別執行如下命令:
cd /opt/
tar -zxvf apr-1.5.2.tar.gz
cd apr-1.5.2
./configure --prefix=/usr/local/apr
make && make install
4)安裝apr-util
分別執行如下命令:
cd /opt/
tar -zxvf apr-util-1.5.4.tar.gz
cd apr-util-1.5.4
./configure --prefix=/usr/local/apr-util --with-apr=/usr/local/apr
make&& make install5)安裝pcre
分別執行如下命令:
cd /opt/
tar -zxvf pcre-8.37.tar.gz
cd pcre-8.37
./configure --prefix=/usr/local/pcre
make&& make install6)安裝Apache
分別執行如下命令:
cd /opt/
tar jxvf httpd-2.4.16.tar.bz2
cd httpd-2.4.16
./configure --prefix=/usr/local/apache --with-apr=/usr/local/apr --with-apr-util=/usr/local/apr-util --with-pcre=/usr/local/pcre
make&& make install至此Apache即安裝完成。
4、執行
1、在目錄/usr/local/apache/bin/目錄下新建一個檔案request.txt,寫入需要post的請求資料。
2、開啟終端,進入root。執行如下命令:
cd /usr/local/apache/bin/
./ab -n 1000 -c 100 -p request.txt -l -T "application/x-www-form-urlencoded" http://111.com
注:其中http://111.com是接收請求的伺服器地址;request.txt檔名可自定。
回車後即開始執行測試程式。
其中遇到一個值得注意的問題,一開始我是在VMWare中安裝redhat來執行ab的,發現執行結果非常不穩定,每次測試的結果差異很大,讓我一直以為是自己程式碼修改的問題,但是反覆嘗試了很久都未能改善,所以就懷疑是虛擬機器的效率問題。後來就在物理機上測試果然一切正常。所以建議大家在物理機環境下進行操作。