1. 程式人生 > >修改Apache Benchmark原始碼實現請求資料隨機的壓力測試

修改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,函式體如下:

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;
}
然後修改函式void write_request(struct connection *c),找到其中如下的一條語句:
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_64

rpm-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_64

2)安裝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 install

5)安裝pcre

分別執行如下命令:

cd /opt/

tar -zxvf pcre-8.37.tar.gz

cd pcre-8.37

./configure --prefix=/usr/local/pcre

make&& make install

6)安裝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的,發現執行結果非常不穩定,每次測試的結果差異很大,讓我一直以為是自己程式碼修改的問題,但是反覆嘗試了很久都未能改善,所以就懷疑是虛擬機器的效率問題。後來就在物理機上測試果然一切正常。所以建議大家在物理機環境下進行操作。