小測幾種python web server的效能
因為換了nginx就不再使用mod_wsgi來跑web.py應用了,現在用的是gevent-wsgi,效果還不錯。但還是想試試別的,比如傳說中超級猛的meinheld什麼的。
軟硬體環境
硬體:
一臺04年初購置的IBM X235伺服器,CPU為Xeon 2.4G兩顆,記憶體1G,100M網絡卡。
軟體:
Ubuntu Server 10.04 LTS
Apache 2.2.14
Nginx 0.7.65
Python 2.6.5
web.py 0.37
mako 0.7.2
sqlalchemy 0.7.8
gevent 0.13.7
gunicorn 0.14.6
meinheld 0.4.15
測試程式碼
有五個版本,分別是:
最基本的WSGI helloworld
def application(environ, start_response):
status = '200 OK'
resp = "Hello world!"
resp_headers = [('Content-type','text/plain;charset=utf-8')]
start_response(status, resp_headers)
return [resp]
最基本的web.py your IP
class yourip: def GET(self): return "Your IP is : %s" % web.ctx.ip
加了mako模板的web.py
class onlymako(BaseHandler):
@expose("yourip")
def GET(self):
return dict(yourip=web.ctx.ip)
加了資料庫的web.py
class onlydb:
def GET(self):
created = web.ctx.provider.once_access(web.ctx.ip)
return "You have logged : %s" % created
和同時加了資料庫和mako模板的web.py —— 這也是最接近實際應用的情況
class makodb(BaseHandler):
@expose("index")
def GET(self):
created = web.ctx.provider.once_access(web.ctx.ip)
return dict(created=created)
測試目標
五種執行環境:
web.py的測試環境app.run
web.py+gevent-WSGI
gunicorn預設(sync)
gunicorn+gevent
gunicorn+meinheld
gunicorn使用 -w 4 引數,經實際比較過,這個引數並不能有效增加rps,但在高併發測試情況下可以在一定程度上減少失敗率。
測試方式
ApacheBench 2.3(Ubuntu Desktop 12.04)
RPS測試引數為 -n 200 -c 22 測五次取rps平均值。
之所以用這樣比較小的引數,是因為再高了,其中某些測試就通不過了。
測試結果
RPS測試 | WSGI helloworld | Web.py YourIP | Web.py+Mako | Web.py +SQLAlchemy (SQLite) | Web.py+Mako +SQLAlchemy (SQLite) | Web.py | Web.py+Mako +SQLAlchemy (Postgresql) |
---|---|---|---|---|---|---|---|
Web.py app.run | 無 | 130 | 93 | 75* | 45* | 59 | 40 |
web.py+gevent | 無 | 422 | 130 | 82 | 54 | 74 | 53 |
gunicorn default | 854 | 439 | 136 | 93 | 66 | 90 | 62 |
gunicorn+gevent | 695 | 291 | 115 | 74 | 56 | 78 | 56 |
gunicorn+meinheld | 3565 | 682 | 160 | 84 | 65 | 98 | 64 |
其中加了“*”的數字發生了資料庫錯誤,僅供參考。
另外,用同樣的引數測了一下Apache2處理靜態檔案的rps為:1780,nginx為:2951。
===附加的分割線===
再附加一個在我的Atom小伺服器上的部分測試結果:
Nginx處理靜態檔案的rps為:4000左右。
WSGI hello world測試:gunicorn+meinheld約為:3800。gunicorn+gevent約為:1100。gunicorn default約為:1400。
your IP測試:gunicorn+meinheld約為:1000。gunicorn+gevent約為:450。gunicorn default約為:700。
相比之下這個Atom小機器比IBM伺服器猛好多。硬體發展速度真是太快了。
附軟硬體環境:
Atom D525 1.6G雙核,2GRAM,FreeBSD 9,Nginx 1.2.2,Python 2.7.3,其它同IBM伺服器。
並且在這個Atom機器上 -w 引數對rps有明顯貢獻…看來是因為老伺服器的問題才效果不明顯,只是不確定是硬體問題還是OS問題。
結論
meinheld的確猛,處理最簡單的WSGI比Apache2處理靜態檔案還要猛一倍,跟Nginx相當甚至更強。
app.run的rps比預想的要好很多,只是併發數真不行,-c 引數略加大就會出現大量失敗測試。
gevent已經足夠好了,不過居然比gunicorn的sync模式還慢真是有點不科學啊。
gunicorn的好處在於管理方便,並且可以靈活使用各種work_class,特別奇怪的一點是居然sync模式也這麼快。
web.py的效能影響還是很明顯的。
模板的影響也很明顯——mako已經算是很快的模板了,真不知道用那些KID之類很慢的模板會是什麼效果。
資料庫的影響更大,不過pgsql的效能居然能跟sqlite差不多,真不知道是sqlite太慢還是pgsql太快…
本來前一陣我剛聽說OpenResty這貨的時候還是很有興趣的,但是現在看到meinheld的表現以後,覺得還是算了吧,畢竟用OpenResty還要去學Lua…現在要學的東西太多,能用Python搞定的事情就不去麻煩Lua了。