內置於燒瓶中的Web服務器並不打算在生產環境中使用,這正是您列出的原因 - 它是單線程的,並且如果有任何請求阻塞時間不長,容易陷入困境。燒瓶文件lists several options for deploying it in a production environment; mod_wsgi
,gunicorn
,uSWGI
等。所有這些部署選項都提供了通過線程,進程或非阻塞I/O來處理併發的機制。但是,請注意,如果您正在執行CPU綁定操作,唯一會提供真正併發性的選項是使用多個進程。
如果要使用tornado
,則需要用tornado
樣式重寫應用程序。由於其架構基於顯式異步I/O,因此如果將其部署爲WSGI應用程序,則無法使用其異步功能。 「tornado
風格」基本上意味着對所有I/O操作使用非阻塞API,並使用子進程處理任何長時間運行的CPU綁定操作。該tornado
文檔介紹瞭如何進行異步I/O調用,但這裏是它如何工作的一個基本的例子:
from tornado import gen
@gen.coroutine
def fetch_coroutine(url):
http_client = AsyncHTTPClient()
response = yield http_client.fetch(url)
return response.body
的response = yield http_client.fetch(curl)
調用實際上是異步的;它將在請求開始時將控制權返回給龍捲風事件循環,並且一旦收到響應就會再次恢復。這允許多個異步HTTP請求同時運行,全部在一個線程內運行。但請注意,fetch_coroutine
中的任何內容不是異步I/O將阻止事件循環,並且在代碼運行時不能處理其他請求。
要處理長時間運行的CPU綁定操作,您需要將工作發送到子進程以避免阻塞事件循環。對於Python,通常意味着使用multiprocessing
或concurrent.futures
。我想看看this question以獲取更多關於如何最好地將這些庫與tornado
進行整合的信息。請注意,您不希望維護大於系統中CPU數量的進程池,因此請考慮在指定時間的情況下,您希望在任何給定時間運行多少個併發CPU限制操作將其擴展到單臺機器之外。
龍捲風文檔has a section dedicated to running behind a load balancer也是如此。他們建議爲此使用NGINX。
只要將'@ tornado.gen.coroutine'裝飾器添加到處理程序中,不會使其異步。你必須在處理程序中實際進行非阻塞調用。如果你在函數中做了任何阻塞操作,無論你是否使用'coroutine'裝飾器,整個事件循環都會被阻塞。 – dano 2014-10-01 01:05:42
你是對的,我的錯。你可以使用grequests來獲得異步請求嗎? – ragingSloth 2014-10-01 01:50:04
'grequests'使用'gevent'來提供異步I/O,是的。如果你使用'tornado',你可能會想使用它的內置'AsyncHTTPClient',因爲它與龍捲風事件循環集成在一起。 – dano 2014-10-01 02:28:58