2012年12月13日

WSGI server / framework benchmark

python 實在是個很有趣,不知道是不是這語言造輪子太容易,
居然有這麼多種 web framework,看到會傻眼....
記得我三四年前查的時候才只有 djangoTurboGears 啊 XD

前端 server 的技術也是,當初都只是傳統的 cgi / fcgi 而已,兩三年沒注意整個世界都變了 ||

這幾天趁新 project 才剛起步,比較空閒的時候挑了幾種 framework 跟 WSGI server 來測試,
framework 挑選的準則基本上是依個人主觀,語法看不順眼的刪掉,
document 沒辦法讓我在五分鐘之內學會寫 hello world 也刪掉。(閒也是有限度的...)
WSGI server 的話大概有三個標準,第一是希望他很單純的接受一個 WSGI application 來跑,
所以像 Tornado 這種還管到 framework 的就出局了,我不喜歡跟單一對象綁太緊...
第二是希望盡可能單純經由 pip 就安裝完畢,因為多數的 PAAS 平台不會讓你另外裝東西,
所以如果要依賴一些 c library 的話 deploy 時就少了很多選擇,
第三就是參考別人的 benchmark report 看看大致上都是那些 server 排比較前面,
不過說實話每份 report 結果都差很多,這也是為什麼我會想要自己測一遍......

就這樣,最後選出來受測的是這些
framework: django, Flask, Bottle, itty-bitty
server: uWSGI, bjoern, Meinheld, Gunicorn

測試工具我主要是用 abab -c100 -n10000 http://10.1.149.161:8080/ 這樣。
其實還有一個 webbench,看人家推薦就用用看。
不過我自己用起來覺得 ab 比較好用,
起碼打到掛掉 ab 看得出來,webbench return 的那個 fail 常常都唬爛....

測試方法是一個一個輪流打開,每次只有一個在跑,
參數的話 access log 都關掉,只留 error log,
worker 數目都設成 [(kernel 數目) * 2 + 1],(在我的機器上就是 9)
application 都是最簡單的 hello world,
詳細的測試 code、server setting、還有指令等等我放在這邊

受測端是 Ubuntu 11.10 oneiric,打人的是 CentOS release 5.8 (Final)。
platform 沒什麼意義,我手上有這兩台就拿來用了。
兩台硬體都是 Intel i5 750, 4GB ram。

總之,performance testing 結果如下:


可以看到 Gunicorn with Meinheld worker class 大致上都是最猛的,
尤其是 bottle 在這上面跑得跟飛的一樣....
不過除此之外其實 uWSGI + nginx 表現也都很好。
bjoern 跟 Meinheld 大概是吃了單一 process 的虧,相較之下結果就不太好,
......不過怎樣都比 fast CGI 快多了 XD

framework 方面,Bottle 相當亮眼啊,比我預計的還要快,不愧是輕量級 framework。
django 這個肥肥的東西慢是可以預見,雖然我已經關掉不少 middleware 跟 plugin 了....
倒是這個 Flask 在搞什麼鬼,號稱輕量結果速度跟 django 差不多甚至更慢,不知道該說什麼 -_-
最後是這個 itty,這東西相當神奇,我本來是看他 source code 只有六百多行,
甚至只有 Bottle 的 1/5,輕成這樣預計應該跑超快,結果大多數時候都是最慢的,
正想罵人的時候突然發現它在 uWSGI 跟 bjoern 上簡直像背了火箭一樣飛,不知道怎麼回事 XD

另外我也測了一下 concurrent capability,
方法是用 ab 一直把 -c 的數目加上去,到它出錯為止。
結果大概是像這樣:
.                    -c      -n
-----------------------------------
gunicorn-meinheld   1500    300000
bjoern               500    200000
meinheld             500    200000
uwsgi (domain)       100    300000
uwsgi (tcp)          500    300000

gunicorn-meinheld 還是最猛的,而且跟別人完全不是同個量級的。
其實有點嚇到,應該是我 nginx 設定的不好,
因為我另外試過拿 nginx 擋在 Gunicorn 前面做 reverse-proxy,
結果反而 500 個 concurrent 左右就開始出錯,而且速度也掉一半。
不過我懶得再研究了,反正 Gunicorn 配 Meinheld worker 的表現沒什麼可以挑剔的地方,
以後大概就是用這個了,也沒什麼 dependency,pip 全部搞定。


Reference:

  1. The Web framework for perfectionists with deadlines | Django
  2. Flask, web development, one drop at a time
  3. Bottle: Python Web Framework
  4. The itty-bitty Python web framework
  5. The uWSGI project
  6. bjoern: Fast And Ultra-Lightweight Asynchronous HTTP/1.1 WSGI Server
  7. Meinheld
  8. Gunicorn - Python WSGI HTTP Server for UNIX
  9. Server Options
  10. Primer to Asynchronous Applications
  11. greenlet: Lightweight concurrent programming
  12. Web micro-framework BATTLE!
  13. gunicorn, uwsgi, fast-cgi, tornado 等
  14. Python WSGI Server(uwsgi, tornado, bjoern, meinheld,gevent)性能测试
  15. Why is setting nginx as a reverse proxy a good idea?

沒有留言:

張貼留言