作了一個 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 直覺。
沒有留言:
張貼留言