Ab - Apache HTTP server benchmarking tool 是 Apache HTTP Server 自帶的壓力測試工具。 Load testing 本身是我學習的一個方向。 ab 作為一個簡單的、典型的工具很適合入門。

Load testing 工具學習,幾乎都至少有 2 部分組成:

  1. 如何產生有效的數據壓力。
  2. 如何得到和讀懂測試報告。

ab 的使用也可以分成這 2 部分。不過 ab 相對與其他 Load testing 工 具 (比如: Apache JMeter) 更加簡單;功能更少。除了看懂報告外,其它功能基本都很好理解。

我的 VimWiki 裏有一些我用到過的用例,和我的部分理解: http://xj-labs.net/dev/ab.html

如何使用 ab 產生數據壓力

ab 是一個 Command-line 工具。用戶通過 Command-line 參數來指定測試參數。比如:

  • “ab -n 10000 -c 100 http://127.0.0.1:2333/”
    表示向 127.0.0.1:2333 server 發送1000個 GET 請求,併發請求數爲 100。

  • “ab -t 60 -c 100 http://127.0.0.1:2333/” 表示向 127.0.0.1:2333 server 發送1000個 GET 請求,併發請求數爲 100。

全部參數可以用 ab -h 來查看。也可以上 Apache 安裝目錄找到對應的 Documentation。 ab 的 Documentation 是 “manual/programs/ab.html.en”。

常用參數大概可以分爲幾個類別:

  • 指定測試的 server 和 HTTP 請求設置:
    • Target URL, 放在 Command-line 的最後一個參數
    • HTTP Method( POST/PUT or GET。默認情況會使用 GET 請求。 如果需要測試 POST 則需要用 -p or -u 指定 POST 的內容文件。
    • HTTP Content-type, 這個是 HTTP 請求 Header 的一個字段, 用來指定協議 Content , 比如 “text/plain” 。 Post method 測試時很有可能需要特殊設置這個字段。用 -T 可以指定。
    • 啟用 HTTP KeepAlive ,默認是不啟用的。用 -k 啟用。
    • Proxy 设置。用来指定连接 Target URL 时用的 Proxy。用 -P 设置。
    • SSL 设置,指定特殊的 SSL 配置当需要测试某些 HTTP(s) 请求时。用 -z 设置。
  • 报告设置:
    ab 的測試報告有三種。
    • 總結報告,會被輸出到 stdout 去。用戶可以自己把結果輸出到文件去。 格式可以是純文本的 text 或是 html (用 -w 指定 html 格式輸出) 。 在這部分報告中可以看到,測試的總的情況,比如: 測試的時間; target server; requests 的個數,流量;以及所有 requests 的匯總報告。
    • Connection timei。用 -g gnuplot-file 來設置。它是一個 csv 文件。 這個文件可以被用來 gnuplot 來繪製圖表。 (實際上所有 csv 文件都可以被 gnupolt 拿來繪圖。) 其中包含了每一個 requests 的具體完成情況。 可以比較充分的反應 Server 在壓力測試情況下的響應狀況。
    • requests 耗時的統計文件。用 -e csv-filename 來設置。它是一個 csv 文件。 這個文件所含有的內容比較簡單、清晰。 他是所有測試中的 requests 耗時排序後的結果。 爲來減小報告的長度,這個報告沒有列出每一個 requests 而只是列出百分比形式的結果序列。
  • 測試的策略:
    ab 测试的最小单位是一个 request,即一個 HTTP(s) 請求發起到結束的過程。 有 2 种測試策略:time limit 和 requests limit 。
    • requests limit
      -n 指定測試發起 requests 的個數。比如: ab -n 10 http://127.0.0.1:2333/ 表示這次測試向 server 發送 10 個 requests。
    • time limit
      用 -t 指定測試運行的時間,以秒爲單位。需要注意的是,ab 內部的預設 50000 個 requests 爲極限。 默認情況超過 50000 個 requests 發起後,即使是測試時間還沒有達到也會結束測試。 這個 50000 的 limit 是編譯時決定的。原因是為了生成最後的 report, ab 會根據 requests 個數在測試開始時生成一個固定大小的 buffer。 所以 requests 個 數是需要在測試開始時決定的。
      有一種方式可以在使用 -t 的情況下指定 requests 個數: 把 -n 參數放在 -t 後面。 ab 在解析到 -n 參數時,會把 requests limit 重新覆蓋。 比如: ab -t 3000 -n 10 http://127.0.0.1:2333/ - 設置最大的 requests 數爲 10, 所以即使時沒有到 3000 秒測試也會結束。同樣如果真的想測試超過 50000 個的 requests 也 可以用這個方式自己設置次數。但如果用 -n 10 -t 3000 這個順序,就不會只發 10 個 requests, 因為 ab 解析 -t 時,會把 requests limit 設置到 50000。
    • 另外一個比較重要的指標是 “concurrency level”。用 -c 指定這個指標。 表示併發的 requests 個數。注意:
      • concurrency 至少要大於 1,並且小於 20000。 比如: -c 1 合法參數, -c -1 是無效的, -c 40000 也是無效的。
      • 如果用 -n 指定了 requests limit,那麼 concurrency 必須小於 requests limit。 比如: -c 10 -n 100 是合法的,-c 10 -n 5則不合法。

如何讀懂 ab 的測試報告

要看懂 ab 的輸出報告,首先應該需要知道 ab 的測試指標,即 request 的定義和它的指標。 其次是 request 結果指標在報告中的表示方式。

request 的測試指標

一個正常 request 的流程如下面這個簡圖所示: (正常是指,沒有遇到類似網路或 Server 問題,不牽涉錯誤處理的情況)

  • 左側是 Client, 右側是 Server 。 從上至下也是時間的流向。
  • Client 用於一個 requests 的流程:
    1. [Begin Connection] 開始建立和 Server 的 Socket 連接
    2. [Connected] 成功建立連接
    3. [Begin write request] 開始發送 HTTP request
    4. [End write request] HTTP 請求發送完畢
    5. [Watting server response] 等待 Server 回應
    6. [Begin receive response] 開始接收 Server 回應
    7. [End receive response] 接收到所有 Server 回應
    8. [Close Connection] 關閉連接

ab-request

ab 的 request 統計指標: ctime, dtime, ttime, wait。

  • ctime:
    ctime = [Connected] - [Begin Connection] 它表示連接建立所花費的時間。 它等於 [Connected] 的時間點減去 [Begin Connection] 的時間點。
    這個值很大程度上和網路環境有關,Server 越“近”可能就越小。也和部分測試參數有關, 比如: “concurrency level” 增大也會增大 ctime; Target URL 是 HTTPS 用於連接的時間也會增大。
    這個值更多說明的是網路環境或者 OS Socket 設置上的問題,對 Server 的實現意義不是很明顯。

  • ttime:
    ttime = [Close Connection] - [Begin Connection] 它表示整個 request 花費的時間。 它等於 [Close Connection] 的時間點減去 [Begin Connection] 的時間點。

  • dtime:
    dtime = ttime - ctime 或者說 dtime = [Close Connection] - [Begin write request] 它表示正個 request 除開建立連接部分所花費的時間。

  • wait:
    wait = [Begin receive response] - [End write request] 它表示 Client 在發送完所有請求數據後, 等待 Server 回應的時間。
    這個值非常有意義,很多程度上說明了 Server 本身的處理能力。

一個簡單的 ab 測試用例

目的是用 ab 來測試一下 Node 的 Cluster 特性: http://nodejs.org/api/cluster.html
通過 ab 比較啟用 Cluster 前、後 Node Server 的處理能力。

Mock Server

為了方便之後的測試,我用 Node 寫了一個簡單 HTTP Mock Server 。 這個 Mock Server 可以在我的 gist 中找到: https://gist.github.com/xiongjia/428402521312456ceccf

啟用這個 Mock Server 的過程:

git clone https://gist.github.com/428402521312456ceccf.git mserv
cd mserv
npm install
node index.js

使用方式已經寫在了 “+README.md” 裏:

  • 默認端口號是 2333
  • 用 node index.js 或 node index.js –cluster 後者會啟用 Node 的 Cluster feature。
  • “/get-data” 測試, Server 會按照客戶端要求來返回 response。 比如: http://127.0.0.1:2333/get-data?len=2048&delay=500 表示 server 在 500 毫秒後, 返回 2048 bytes 的數據。
  • “/basic-auth”,是基本的 HTTP authorization 測試: http://127.0.0.1:2333/basic-auth

用 ab 測試 Node 的 Cluster 特性

Node 提供 Cluster 特性,讓多進程協同工作。以達到充分利用 Server CPU 的目的。 這裡的目的是用 ab 來測試一下啟用 Cluster 前後 Server 處理時間的變化。

  • 測試沒有啟用 Cluster 情況下的 Server
    • 用 node index.js 啟動之前提到的 Mock Server。(這種狀態下,Node 只開啓一個進程來提供服務。)
    • ab 測試策略: ab -n 20000 -c 200 -g disable-cluster.tsv http://127.0.0.1:2333/get-data?len=8192&delay=500
    • 以 200 爲併發數,總共發送 20000 個請求,並且讓 server 在 500 ms 後返回 8192 bytes 數據回來。 報告放入 “disable-csv.tsv” 文件中。
  • 測試啟用 Cluster 情況下的 Server
    • 用 node index.js –cluster 啟動之前提到的 Mock Server。 這種狀態下,Node 會用開多個進程來提供服務。併發性應該更高。 併發數取決與 CPU 個數,我是在 8 cpu 的機器上測試的。
    • 用同樣的 ab 測試策略,只是改一下輸出報告的文件名: ab -n 20000 -c 200 -g cluster.tsv http://127.0.0.1:2333/get-data?len=8192&delay=500

最後用 gnupolt 來比較一下 2 種測試報告。
在下面這個報告中,綠線代表 “Disable Cluster” 的情況,紅線代表 “Enable Cluster” 的情況。 Y 軸代表耗時(越小越好),測試中設置了 “delay=500” 所以 Y 軸是從 500 開始的。 X 軸代表 Request 的個數所以是從 0 到 20000 。

雖然不是很明顯,不過可以看出紅線更加平滑一些。也就是說啟用 Cluster 後 Node Server 的處理速度更快一些。 ab-request

生成上面這個報告圖片所使用的 gnuplot 腳本:

  • 第一部分用來設置輸出格式到 .png 。
  • 第二部分用來設置圖片的 title 和 X,Y 軸信息。
  • 最後一部分把 “cluster.tsv” 和 “disable-cluster.tsv” 的第 5 列 (ttime) 放入 gnuplot 的數據輸入。
# set output format
set terminal png
set output "cluster.png"
set size 1,0.7

# set graph format
set title "Node Cluster Test"
set grid y
set xlabel "Request"
set ylabel "Response time (ms)"

# set output data
set datafile separator "\t"
plot "cluster.tsv" using 5 smooth sbezier with lines title "Enable Cluster", \
  "disable-cluster.tsv" using 5 smooth sbezier with lines title "Disable Cluster"

其它

  • ab 產生的其它報告:
    基本只要懂得了 ab request 的指標,就應該很明白這些 report 的信息了。 在 Vimwiki 裏做了比較多的說明: http://xj-labs.net/dev/ab.html

  • ab 的優缺點

    • 優點: 使用/操作上簡單;易理解。輸出報告簡單、清晰。
    • 缺點:
      個人覺得這些缺點在使用 Apache JMeter 時是可以避免的,只是 JMeter 學習起來比 ab 麻煩許多。
      • HTTP(s) 之外的沒有支持;HTTP(s) 本身如果 request 很複雜也比較難用。
      • 不能對每一個具體 request 做額外的設置。每一個 request 的行為必須一樣,不能在參數上做出改動。
      • 測試流程上無法控制,比如:每個 request 都是連續的,有是會讓 Server 誤認有人在攻擊 Server。
      • 測試以一台機器爲單位,不能把測試分佈到多台機器上。


blog comments powered by Disqus

Published

18 May 2014

Tags