用 grequests 作 stress test

作了一個 C10K 的 server 後, 還要作 stress test 才能驗證 server 真的挺得住 C10K 的連線。試了幾套工具, 最後覺得 grequests 最好用 (用 gevent monkey patch 的 requests), 用法就這麼簡單:

import grequests

def exception_handler(request, exception):
    print "Request failed: %s" % exception

url = 'SERVER_URL'
rs = [grequests.post(url, data={...})
      for i in range(10000)]
rss = grequests.map(rs, size=1000, exception_handler=exception_handler)

這樣就寫好一個會同時產生 1k 個連線, 總共產生 10k 個連線的 client。因為是直接寫程式, 可以自訂各式各樣的內容, 測得出真正的效果, 不會被簡單的 cache 消掉絕大多數的 requeests。若要改用 get 就用 grequests.get(url) 產生 request, 詳細用法見 requests

幾個測試情境和作法:

  • Connection bound: 提升 size 數, 或多跑幾個 client
  • CPU bound: 同上, 故意使用耗 CPU 的 API
  • Memory bound: 依 API 的性質, 產生 1MB 或更大的資料, 由 data=... 傳過去

grequests.map() 不設 size 的話, 會盡可能產生最多連線, client 有可能自己先爆掉。依自己的網路環境和 server 狀況, 可試看看不同的值。

執行前記得先用 ulimit -n 提升 open file number, 不過要用 root 才能提升, 作法如下:

$ sudo bash
$ ulimit -n 50000
$ su YOUR_ID

這樣可以用一般帳號測試, 但保有 max open file number = 50k。

以下是我試過但不管用的方法, 憑印象寫下放棄使用的原因 (不見得是工具不好):

  • ab: 很久以前用過覺得不夠順手, 查到文章推薦用 httperf, 這回我就跳過 ab 了。
  • httperf: 雖然有 --wsesslog 可以讀文字檔產生不同內容, 還是不夠彈性。另外有遇到 open too many files 的問題, 似乎要編程式才能提升 limit, 就懶得再試了
  • loadtest: 看起來不錯, 可用 -R 指定 script自訂程式, 由 loadtest 幫忙處理其它事, 不過沒有試成功, 就試別套了
  • nodeload: 還不錯用, 可以自訂程式, 執行後還會自動產生報表, 附一個 local http server 跑在 port 8000 可以即時看報表變化。不過量大了以後會炸, 有些 bug, 作者又說沒在維護了, 就放棄它了。
  • Btw, 用這些工具的時候, 都要自己設好 http header 才可以使用 POST, 不如 requests 直覺。

留言

這個網誌中的熱門文章

virtualbox 使用 USB 裝置

熟悉系統工具好處多多

如何 git merge 更改檔名的檔案