PythonWeb程序的部署方案
綜合而言,高性能的Pythonweb站點部署方式首推nginx+uwsgi
apache+mod_wsgi是簡單穩定但性能一般的方式
API服務器可以直接使用tornado或者gevent
mod_python
非常原始的cgi模式部署python已經沒有什么好介紹了。對于不太追求性能的管理系統和網站來說,使用Apache部署是一個不錯的選擇。較早的時候,使用mode_python部署python的web應用十分流行,在Django0.96的時候官方文檔甚至推薦這種方式。
它將Python解釋器嵌入到Apacheserver,以提供一個訪問Apacheserver內部的接口。mod_python在現在看來性能是不佳的,每一個http請求mod_python都會由一個進程初始化python解釋器、載入代碼、執行、然后銷毀進程。
mod_wsgi
如果非要用Apache來部署python應用,mod_wsgi是一個更好的選擇。WSGI全稱是WebServerGatewayInterface,由PEP-333定義。基本上所有的pythonweb框架都實現了wsgi接口,用mod_wsgi能部署任何實現了wsgi的框架。實際上,不需要任何框架也可以用mod_wsgi部署python程序。使用mod_wsgi的daemon模式,python程序會常駐內存,不會有很大的初始化和銷毀進程方面的開銷,所以性能是好于mod_python的。綜合來說,使用Apache部署pythonweb程序,推薦使用mod_wsgi的daemon模式。
Fastcgi
先說觀點:不建議用fastcgi的方式部署Pythonweb。
前幾年由于lighttpd風頭正勁和豆瓣的成功案例,fastcgi是一種很流行的部署方式。fastcgi與具體語言無關,也與web服務器無關。是一種通用的部署方式。fastcgi是對于cgi的增強,CGI程序運行在獨立的進程中,并對每個Web請求建立一個進程。面對大量請求,進程的大量建立和消亡使操作系統性能大大下降。
與為每個請求創建一個新的進程不同,FastCGI使用持續的進程來處理一連串的請求。這些進程由FastCGI服務器管理,而不是web服務器。當進來一個請求時,web服務器把環境變量和這個頁面請求通過一個socket比如FastCGI進程與web服務器都位于本地)或者一個TCPconnection(FastCGI進程在遠端的serverfarm)傳遞給FastCGI進程。
主流的web服務器,Apache,lighttpd,nginx都支持fastcgi,在幾年前,lighttpd的mod_fcgi模塊性能強勁,lighttpd+fastcgi十分流行。無論是python,ruby還是php,都有大量的站點使用這種方式部署。由于nginx的崛起,現在很少有人使用lighttpd了。
fastcgi并不是專門為python設計,并不是所有的python框架天然的支持fastcgi,通常需要flup這樣的容器來配適。flup由python編寫,和專門的c實現的wsgi容器比起來性能顯得相當不堪。fastcgi的穩定性對于新興的wsgi容器來說也有差距。無論從哪個方面來看,部署pythonweb程序,fastcgi都已經是過去式。
uwsgi
前幾年nginx還未內置uwsgi模塊的時候,部署uwsgi還是一件挺麻煩的事情。隨著能夠在nginx中直接使用uwsgi模塊,uwsgi已經是最可靠,最方便的高性能pythonweb程序的部署方式了。
在1U的四核XEON服務器上,一個簡單的wsgihandler甚至能用AB壓到8000以上的qps,這已經是完爆tornado,接近gevent的性能了。同時,uwsgi的穩定性極好。之前我們有個每天500w-1000w動態請求的站點使用uwsgi部署非常穩定,在一個渣HP1U服務器上,基本不用管它。
上面提到的部署方式都是相對于web網站的方式,在移動互聯網的時代,我們需要的是高性能的API服務,上面這些都是過時的東西。
tornado
tornado號稱高性能,如果拿他寫網站,其實一般般,只不過跟uwsgi加一些簡單框架差不多而已。它真正的作用,是用來寫API服務器和長連接的服務器。
由于tornado能夠直接處理http請求,很多人直接拿他來裸奔直接提供服務。這種方式是不可取的,單線程的tornado只能利用cpu的一個核心,并且一旦阻塞直接就廢了。通常情況下,由supervisor啟動多個tornado進程,通過nginx進行反向代理負載均衡。nginx1.14以后的版本反向代理支持長連接,配合tornado的comet效果很好。
tornado還有一些比較奇葩的用法,比如用來做wsgi容器之類的。
gevent
gevent是一個神器,能做的事情很多。在web方面,處理http請求,用起來其實跟tornado差不多,但是要簡陋很多,cookie之類的都沒有。用gevent寫的一些API服務,部署方式還是類似tornado,用supervisor管理多個守護進程,通過nginx做負載均衡。同樣的它的奇葩用法也和tornado一樣,可以當wsgi容器用。