http_load是一款測試web服務器性能的開源工具,從下面的網址能夠下載到最新版本的http_load:html
http://www.acme.com/software/http_load/ (頁面實在太簡陋……)web
十分使人欣慰的是,這個軟件一直在保持着更新(不像webbench,已是十年的老古董了。webbench的源碼分析請參考:http://www.cnblogs.com/xuning/p/3888699.html ),而且更新頻率還蠻高的樣子。我在下載了2014年8月2號的版本後,緊接着8月14號再查看,就又有了一個新的版本。這篇文章分析的http load版本是「http_load 02aug2014」,好在每一個版本之間差異很是小,本文仍是具備較好的通用性的。數組
下載並解壓縮以後,進入工具的根目錄直接make,就能夠獲得可執行的工具。其使用方法以下圖所示:服務器
圖中所示的url.txt內容是若干url連接,每行一個,好比:http://127.0.0.1:80/index.html。數據結構
詳細說明一下使用格式:併發
./http_load [-checksum] [-throttle] [-proxy host:port] [-verbose] [timeout secs] [-sip sip_file]socket
-parallel N | -rate N [-jitter]函數
-fetches N | -seconds N工具
url_file源碼分析
選項與參數:
-fetches:總計要訪問url的次數,不管成功失敗都記爲一次,到達數量後程序退出。
-rate:每秒訪問的次數(即訪問頻率),控制性能測試的速度。
-seconds:工具運行的時間,到達seconds設置的時間後程序退出。
-parallel:最大併發訪問的數目,控制性能測試的速度。
-verbose:使用該選項後,每60秒會在屏幕上打印一次當前測試的進度信息。
-jitter:該選項必須與-rate同時使用,表示實際的訪問頻率會在rate設置的值上下隨機波動10%的幅度。
-checksum:因爲要訪問某個url不少次,爲了保證每次訪問時收到的服務器回包內容都同樣,能夠採用checksum檢查,不一致會在屏幕上輸出錯誤信息。
-cipher:使用SSL層的時候會用到此參數(url是https開頭),使用特定的密碼集。
-timeout:設置超時時間,以秒爲單位,默認爲60秒。每超過一次則記爲一次超時的鏈接
-proxy:設置web代理,格式爲-proxy host:port
-throttle:限流模式,限制每秒收到的數據量,單位bytes/sec。該模式下默認限制爲3360bytes/sec。
-sip:指定一個source ip文件,該文件每一行都是ip+port的形式。
須要特別說明的是,-parallel參數和-rate參數中必須有一個,用於指定發請求包的方式;-fetches和-seconds兩個參數必須有一個,用於指定程序的終止條件。
webbench是另一款網頁性能測試工具,它的源碼分析能夠參考以下鏈接:
http://www.cnblogs.com/xuning/p/3888699.html
webbench採用多進程發包,最多支持3萬併發量,而http_load採用單一進程並行複用方式發包。因爲只有一個進程,http_load對於機器資源消耗較小,性能要求不高,但它的劣勢就是最大併發量比webbench要少量多,只能達到千的量級。在不少場景中,幾千的量級也已經綽綽有餘了,所以具體工具的選用還要看實際狀況。
咱們分別使用webbench和http_load對同一個URL進行壓力訪問,結果以下。
[horstxu@vps ~/webbench-1.5]$ ./webbench -t 30 -c 1000 http://127.0.0.1:8080/user.png Webbench - Simple Web Benchmark 1.5 Copyright (c) Radim Kolar 1997-2004, GPL Open Source Software. Benchmarking: GET http://127.0.0.1:8080/user.png 1000 clients, running 30 sec. Speed=180340 pages/min, 5268934 bytes/sec. Requests: 90170 susceed, 0 failed. [horstxu@vps ~/http_load-02aug2014]$ ./http_load -parallel 1000 -fetches 90000 url.txt 90000 fetches, 830 max parallel, 1.2933e+08 bytes, in 30.5439 seconds 1437 mean bytes/connection 2946.58 fetches/sec, 4.23424e+06 bytes/sec msecs/connect: 0.772754 mean, 215 max, 0.025 min msecs/first-response: 17.2259 mean, 288.007 max, 1.735 min HTTP response codes: code 200 – 90000
若是進行一下換算,webbench測得的頁面RPS爲180340 pages/min = 3006rps,這與http_load的測試結果2946fetches/sec結果是很接近的,而且,http_load統計數據更加全面,數據校驗也更加完善。對於每秒流量數據,webbench的結果是5268934bytes/sec,http_load是4234240bytes/sec。這其中的差異在於,http_load在統計時剔除了http報文的頭部(head),而webbench是沒有剔除頭部的。接下來咱們來領略一下http_load的實現原理。
程序的工做流程能夠用下面這幅圖來表示,執行時程序主要環節位於流程圖中的循環內。http_load爲單一進程的程序,所以進程內的全部調用都是非阻塞方式進行, 保證程序的流暢度。程序的執行過程主體在一個大循環當中,不間斷進行結束條件的斷定和超時斷定。時間管理方式是使用拉鍊式哈希表,超時狀況下即運行超時處理函數。
5.1 程序執行過程解析
若是使用簡化的代碼來描述上一節所述的流程圖,能夠參考下圖。流程圖中的循環也就是主函數中的for循環。在主循環內主要作4件事情。首先,檢測當前程序是否知足終止條件,若是知足,則調用結束函數退出程序,不然進行下一步。而後,採用select監聽描述符狀態,一旦出現可讀或可寫狀態的描述符,則採用handle_connect與handle_read兩函數分別進行處理。須要提醒的是,源程序在處理讀取socket緩衝區這一段爲了完美剔除掉http請求報文的頭部,耗費了大量的代碼。再而後,循環尾部執行超時檢測,檢查當前時間有沒有超過在哈希表中註冊的每個時間戳,若是超過,則要執行其對應的超時處理函數。具體的時間戳管理方法見下文。源碼中共有5種時間戳須要註冊,分別對應着5個超時處理函數,請參考圖中的超時處理函數集合。
5.2 三個重要的結構體
下圖中詳細描述了三個源碼中最爲重要的結構體。首先,程序採用全局變量connections數組控制每個TCP鏈接,connections數組中每一個元素都是一個指向connection結構體的指針。connection結構體包含了用於記錄測試數據的變量,鏈接狀態的控制變量,以及最開始從文件中讀取的鏈接配置信息。第二個結構體爲url結構體,在http_load當中,想要請求的url存儲在文件內,能夠大於一個。這些URL的信息會被讀取至由指向url結構體的指針組成的urls數組。請求會隨機發向這些數組。相比webbench,http_load的一個優點是它的數據校驗環節。每個url會配有返回請求的checksum值,用於校驗每次請求同一個url返回的內容是否一致。第三個結構體是時間管理方法中組成拉鍊式哈希表的每個節點。它包含了指向超時處理函數的指針,以及記錄超時時間的變量。
5.3 時間戳管理方法
http_load中最爲巧妙的就是它的時間管理方法。在該工具中,有不少須要定時觸發的地方,好比每隔一段時間輸出一份測試進度彙報;連接超過必定時間未響應則記爲超時,輸出超時錯誤信息;設定發送頻率,每隔一段時間發出一個請求等等。這些時間戳和其超時觸發的函數以Timer結構體的形式,所有註冊於拉鍊法構成的哈希表中。每一個鏈表都是以時間戳順序從早到晚依次排列。這樣,在每個for循環執行超時檢測的部分,咱們能夠很方便地判斷出當前時間是否已經超過了時間戳的時間,若是超過,則執行超時處理函數。同時,這樣的數據結構也提升了插入新時間戳的效率。
http_load與webbench都是很經常使用的壓測工具,若是配合使用,結果作對比,既是對測得結果的校驗,也能幫助熟悉兩種工具的優劣。http_load的設計思路也可使用到業務測試工具中來,幫助開發出更高效的壓測工具。