Python Web 程序的部署方案
綜合而言, 高性能的Python web站點(diǎn)部署方式首推 nginx + uwsgi
apache + mod_wsgi 是簡單穩(wěn)定但性能一般的方式
API服務(wù)器 可以直接使用tornado或者gevent
mod_python
非常原始的cgi模式部署python已經(jīng)沒有什么好介紹了。對(duì)于不太追求性能的管理系統(tǒng)和網(wǎng)站來說催训,使用 Apache 部署是一個(gè)不錯(cuò)的選擇。較早的時(shí)候盒使,使用 mode_python 部署python的web應(yīng)用十分流行,在Django 0.96 的時(shí)候官方文檔甚至推薦這種方式射富。
它將Python解釋器嵌入到Apache server,以提供一個(gè)訪問Apache server內(nèi)部的接口循榆。mod_python 在現(xiàn)在看來性能是不佳的捅儒,每一個(gè)http請(qǐng)求 mod_python 都會(huì)由一個(gè)進(jìn)程初始化python解釋器煤禽、載入代碼、執(zhí)行岖赋、然后銷毀進(jìn)程檬果。
mod_wsgi
如果非要用Apache來部署python應(yīng)用,mod_wsgi是一個(gè)更好的選擇唐断。WSGI 全稱是 Web Server Gateway Interface ,由 PEP-333 定義选脊。 基本上所有的python web框架都實(shí)現(xiàn)了wsgi接口,用mod_wsgi 能部署任何實(shí)現(xiàn)了wsgi的框架脸甘。實(shí)際上恳啥,不需要任何框架也可以用mod_wsgi 部署python程序。使用mod_wsgi的daemon模式丹诀,python程序會(huì)常駐內(nèi)存钝的,不會(huì)有很大的初始化和銷毀進(jìn)程方面的開銷,所以性能是好于mod_python的铆遭。綜合來說硝桩,使用Apache部署python web程序,推薦使用mod_wsgi的daemon模式枚荣。
Fastcgi
先說觀點(diǎn):不建議用fastcgi的方式部署Python web碗脊。
前幾年由于lighttpd風(fēng)頭正勁和豆瓣的成功案例,fastcgi是一種很流行的部署方式橄妆。fastcgi與具體語言無關(guān)衙伶,也與web服務(wù)器無關(guān)祈坠。是一種通用的部署方式。fastcgi是對(duì)于cgi的增強(qiáng)矢劲,CGI程序運(yùn)行在獨(dú)立的進(jìn)程中赦拘,并對(duì)每個(gè)Web請(qǐng)求建立一個(gè)進(jìn)程。面對(duì)大量請(qǐng)求卧须,進(jìn)程的大量建立和消亡使操作系統(tǒng)性能大大下降另绩。
與為每個(gè)請(qǐng)求創(chuàng)建一個(gè)新的進(jìn)程不同,F(xiàn)astCGI使用持續(xù)的進(jìn)程來處理一連串的請(qǐng)求花嘶。這些進(jìn)程由FastCGI服務(wù)器管理笋籽,而不是web服務(wù)器。 當(dāng)進(jìn)來一個(gè)請(qǐng)求時(shí)椭员,web服務(wù)器把環(huán)境變量和這個(gè)頁面請(qǐng)求通過一個(gè)socket比如FastCGI進(jìn)程與web服務(wù)器都位于本地)或者一個(gè)TCP connection(FastCGI進(jìn)程在遠(yuǎn)端的server farm)傳遞給FastCGI進(jìn)程车海。
主流的web服務(wù)器,Apache,lighttpd,nginx 都支持fastcgi隘击,在幾年前侍芝,lighttpd的mod_fcgi模塊性能強(qiáng)勁,lighttpd+fastcgi十分流行埋同。無論是python,ruby還是php州叠,都有大量的站點(diǎn)使用這種方式部署。由于nginx的崛起凶赁,現(xiàn)在很少有人使用lighttpd了咧栗。
fastcgi 并不是專門為python設(shè)計(jì),并不是所有的python框架天然的支持fastcgi虱肄,通常需要flup這樣的容器來配適致板。flup由python編寫,和專門的c實(shí)現(xiàn)的wsgi容器比起來性能顯得相當(dāng)不堪咏窿。fastcgi的穩(wěn)定性對(duì)于新興的wsgi容器來說也有差距斟或。無論從哪個(gè)方面來看,部署python web程序集嵌,fastcgi 都已經(jīng)是過去式萝挤。
uwsgi
前幾年nginx還未內(nèi)置uwsgi模塊的時(shí)候,部署uwsgi還是一件挺麻煩的事情纸淮。隨著能夠在nginx中直接使用uwsgi模塊平斩,uwsgi已經(jīng)是最可靠,最方便的高性能python web程序的部署方式了咽块。
在1U的四核XEON服務(wù)器上绘面,一個(gè)簡單的wsgi handler甚至能用AB壓到8000以上的qps,這已經(jīng)是完爆tornado,接近gevent的性能了。 同時(shí),uwsgi的穩(wěn)定性極好揭璃。之前我們有個(gè)每天500w-1000w動(dòng)態(tài)請(qǐng)求的站點(diǎn)使用uwsgi部署非常穩(wěn)定晚凿,在一個(gè)渣HP 1U 服務(wù)器上,基本不用管它瘦馍。
上面提到的部署方式都是相對(duì)于web網(wǎng)站的方式歼秽,在移動(dòng)互聯(lián)網(wǎng)的時(shí)代,我們需要的是高性能的API服務(wù)情组,上面這些都是過時(shí)的東西燥筷。
tornado
tornado 號(hào)稱高性能,如果拿他寫網(wǎng)站院崇,其實(shí)一般般肆氓,只不過跟uwsgi加一些簡單框架差不多而已。它真正的作用底瓣,是用來寫API服務(wù)器和長連接的服務(wù)器谢揪。
由于tornado能夠直接處理http請(qǐng)求,很多人直接拿他來裸奔直接提供服務(wù)捐凭。這種方式是不可取的拨扶,單線程的tornado只能利用cpu的一個(gè)核心,并且一旦阻塞直接就廢了茁肠。通常情況下患民,由supervisor啟動(dòng)多個(gè)tornado進(jìn)程,通過nginx進(jìn)行反向代理負(fù)載均衡垦梆。nginx 1.14 以后的版本反向代理支持長連接酒奶,配合tornado的comet效果很好。
tornado還有一些比較奇葩的用法奶赔,比如用來做wsgi容器之類的。
gevent
gevent是一個(gè)神器杠氢,能做的事情很多站刑。在web方面,處理http請(qǐng)求鼻百,用起來其實(shí)跟tornado差不多绞旅,但是要簡陋很多,cookie之類的都沒有温艇。用gevent寫的一些API服務(wù)因悲,部署方式還是類似tornado,用supervisor管理多個(gè)守護(hù)進(jìn)程勺爱,通過nginx做負(fù)載均衡晃琳。 同樣的它的奇葩用法也和tornado一樣,可以當(dāng)wsgi容器用。