http://blog.csdn.net/raptor/article/details/8038476
因為換了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
最基本的web.py your IP
加了mako模板的web.py
加了數據庫的web.py
和同時加了數據庫和mako模板的web.py —— 這也是最接近實際應用的情況
五種運行環境:
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了。
上次的測試見《小測幾種python web server的性能》。
前兩天參加了PyCon2012上海站。雖然今年的PyCon被各種吐槽,但還是有點收獲的。比如ShellXu的元編程,賴總的state/message,沈大俠談的pypy等。
回來就想測一下用pypy跑web應用看看性能如何。順便也對上次的測試范圍作了點擴大化。
PyCon上談到的Pyramid我雖然沒用過,但是前身Pylons和Turbogears我是用過的,只是現在對這種重量級的東西興趣不大。
輕量級的框架除了上次測試用到的web.py以外,bottle和flask也是很熱的東西,尤其是flask,但是因為它對Werkzeug的依賴令我不是很喜歡——我不喜歡名字不好念的東西,除了Werkzeug以外還有像Django這種。
不過這次還是都拿來測了。軟硬件環境與上次測試相同。測試代碼功能都是 your IP。bottle和flask的測試代碼由令狐蟲(http://ch-linghu.me/blog/)友情提供,特此鳴謝。
Server都是用的gunicorn default(sync),單進程。沒有特別精確統計,取近似平均值。
RPS測試 | WSGI helloworld | Web.py YourIP | Bottle Your IP | Flask Your IP |
---|---|---|---|---|
python | 850 | 440 | 580 | 400 |
pypy(*) | 1100 | 800 | 1000 | 600 |
就這個結果來看,pypy的作用還是比較明顯的。另外flask看上去也一般啊,雖然號稱擴展能力強,不知道擴下去性能是不是會影響更大。但bottle的確是很不錯的樣子。
(*)當然因為pypy是JIT方式運行的,所以有一個“預熱”的過程。請求量過小的時候不但不會更快,反而會慢很多。基本上在“冷”狀態下,pypy環境下的RPS只有python環境的一半不到。需要有連續大量請求之后才能達到“熱”狀態。上面的RPS數據都是“熱”狀態的結果。
達到“熱”狀態的過程也各不相同。標准WSGI在幾百個請求之后即可達到,bottle大概需要一千多個請求,web.py需要將近一萬個請求,而flask要超過一萬。
另外,就測試的軟硬件環境來說,gunicorn default(sync)單進程最高只能達到130個並發左右,4進程可以達到270個並發左右。因為換用不同的框架結果都是如此,當然標准WSGI會略高一些(單進程170左右),所以主要應該還是gunicorn決定。
換用gunicorn+gevent測試的話,所有框架上到單進程1000並發沒問題,只是RPS會有相應下降而已。這個時候就體現出gevent相比sync的優勢所在了——雖然低並發時sync速度比gevent還快,但是在高並發下,sync直接死掉(無響應直至超時),gevent只是速度慢了而已。
同樣換用gunicorn+meinheld,最高並發也只能到260而已,只比sync模式高一倍,但還是遠低於gevent。而且meinheld的表現比較奇怪,一開始還可以接受1000並發的,然后就越來越少。另外,它的表現也與gevent不同,gevent在高並發下是一開始就按比較低RPS工作,而meinheld則是仍然以高RPS工作,但到后面就會爆掉(客戶端顯示連接被服務端中斷)。
經令狐分析,可能的原因是這樣的:
sync從字面上理解應該是使用線程阻塞模式,所以在低並發下可以利用到服務器的多核,所以RPS比gevent要高。但是在高並發下,因為線程過多,導致線程切換成本過高失去響應。
meinheld應該也是使用了多線程(同時使用greenlet的協程),所以性能最好,但是在高並發下同樣會面臨與sync一樣的多線程問題。
gevent則勝在輕量,雖然沒有多線程利用多核的優勢,但同樣可以用多進程來利用,而且在高並發的時候,處理不了的請求是在排隊中,所以不會爆掉或死掉,只是RPS下降而已。當然,在極端高並發的情況下,請求隊列是有可能溢出的,但那已經是比sync/meinheld高得多得多的並發了。
不過之前對meinheld過於樂觀的看法是需要改變了,因為在同樣高並發的情況下,nginx毫無壓力,雖然RPS下降不少,但仍然是遠高於gevent,更不用說已經趴下的sync和meinheld……
最后,在測試中還發現了bottle的一個性能問題:404錯誤的響應比正常頁面慢很多。令狐因此對測試程序作了改進,加了一個自定義404頁面,這樣404的響應就和正常頁面差不多了。這一點在使用bottle時需要作為一個注意事項加以考慮。
本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。