2014-02-27 51 views
21

我讀this關於龍捲風:龍捲風VS WSGI(有gunicorn)

在另一方面,如果你已經有了一個WSGI應用程序,並想在一個速度極快的tornado.httpserver.HTTPServer運行 ,用 tornado.wsgi.WSGIContainer包裝它。但你需要小心。由於您的 原始應用程序未準備好用於異步服務器,並且 將進行大量IO計算,因此它將阻止其他請求,而 生成響應(將接受並緩衝 ,但排隊等待稍後處理)。

而且Guincorn說:

「的UNIX一個Python WSGI HTTP服務器。這是一個從Ruby的Unicorn項目移植過來的前叉工作者模型 。

  1. 那麼Gunicorn會產生工作進程來處理請求?
  2. 每個工作人員提出一個請求?
  3. 儘管龍捲風將使用epollkqueue在一個過程中完成工作(無主/輔助過程)?
  4. 因此,如果我使用阻塞調用(如處理程序的get/post函數中的requests.get),這將阻止所有請求處理或僅處理當前請求?

回答

30

如果您在Tornado上運行WSGI應用程序,那麼Tornado和gunicorn之間沒有太大差別,只要WSGI請求正在被處理在特定過程中的應用程序。在gunicorn的情況下,因爲它只有一個線程處理請求,並且在Tornado的情況下,因爲主要事件循環在此期間永遠不會運行以處理任何併發請求。

在龍捲風的情況下,實際上也存在隱患。

對於gunicorn,由於只有一個請求線程,工作進程一次只能接受一個Web請求。如果有併發請求觸發服務器,則它們將由任何其他可用的工作進程處理,因爲它們全都共享相同的偵聽器套接字。

儘管在Tornado中,WSGI應用程序下層的異步性意味着一個進程可以同時接受多個請求。它們將在請求標題和內容被讀取時初始交錯,在調用WSGI應用程序之前,Tornado預讀入內存。當整個請求內容被讀取後,控制權將交給WSGI應用程序來處理該請求。與此同時,只要WSGI應用程序處理第一個請求,由請求標頭和內容尚未讀取的同一進程處理的併發請求將被阻塞。

現在,如果您只有一個Tornado進程,這並不是什麼大問題,因爲無論如何這些請求都會被序列化,但是如果您使用的是gunicorn的龍捲風工作模式,以便使多個Tornado工作進程共享相同的偵聽器這可能是非常糟糕的插座。這是因爲異步層導致的單個進程的貪婪性質,意味着當可能有另一個可以處理它的工作進程時,請求可能在進程中被阻塞。

總之,對於單個Tornado Web服務器進程,您一直只能夠處理一個請求。在gunicorn中,可以有多個工作進程來允許同時處理請求。雖然使用Tornado的多進程設置,但您可能會阻止請求。

因此,Tornado對於非常小的自定義WSGI應用程序來說非常有用,因爲它們的功能不是很多,因此響應速度非常快,但它可能會讓您在運行阻塞WSGI應用程序的情況下長時間運行請求。 Gunicorn因此會更好,因爲它具有處理併發請求的適當能力。 gunicorn雖然是單線程,雖然需要多個工作進程,但它會使用更多的內存。

所以他們都有權衡,在某些情況下,使用通過多線程提供併發性的WSGI服務器以及多個工作進程可以更好。這允許您處理併發請求,但不會通過需要很多工作進程來消除內存使用。同時,您需要在使用多個進程的情況下平衡每個進程的線程數量,以免在CPU繁重的應用程序中不適當地受到GIL的影響。

具有多線程能力的WSGI服務器的選擇是mod_wsgi,uWSGI和女服務員。對於女服務員來說,儘管你只限於單一的工作人員流程。

總而言之,最好的WSGI服務器真的很大程度上取決於您的Web應用程序的具體情況。沒有一個WSGI服務器是最好的。

+0

非常感謝您的詳細解釋。所以如果出現C10K問題,那麼帶有gunicorn的wsgi會更好。你能否給我更多的解釋:「這是因爲由異步層產生的單個進程的貪婪性質,意味着當可能有另一個可以處理它的工作進程時,請求可能在進程中被阻塞,進程共享相同的監聽端口,爲什麼另一個工作進程無法處理傳入的請求? – schemacs

+1

因爲第一個工作進程已經接受套接字連接並開始從中讀取數據。另一個進程無法接管當時的連接。與爲WSGI模塊描述的內容類似的問題,如http://blog.dscpl.com.au/2009/05/blocking-requests-and-nginx-version-of.html –

+1

至於神話般的C10K,在WSGI應用程序中將nginx粘在gunicorn的前面對此沒有多大幫助。 gunicorn可以處理的併發請求的數量仍然受限於可以容納多少內存的進程,這是因爲在Python的GIL工作方式中,擁有比處理器內核更多的工作進程在某些情況下可能會損害性能一個多處理器系統。 –