2015-06-06 129 views
0

我想了解一些龍捲風和異步的概念。如果我們有兩個連接到Tornado服務器T的會話X和Y.龍捲風異步基本概念

現在假設X執行阻塞10秒的數據庫寫入。在那個時期,Y從T請求一些東西。T在服務之前是否必須等待X完成寫操作?

我以爲龍捲風會產生兩個實例並分別將它們從X切換到Y?

回答

2

龍捲風是否可以以異步方式處理數據庫連接取決於您正在使用的數據庫庫。對於異步執行的數據庫查詢,他們必須使用Tornado的IOLoop,如果他們不這樣做,則在發送數據庫查詢並收到響應時,Tornado將會阻塞。

因此,在您的示例中,如果數據庫庫不使用底層Tornado IOLoop,那麼X會阻塞10秒,並且在數據庫寫入X後完成Y(和任何其他請求),但是如果數據庫庫使用Tornado IOLoop並將X實現爲執行數據庫寫入時產生的異步處理程序,則可以在Tornado的IOLoop等待來自數據庫的X寫入數據庫請求響應時處理Y.

作爲MongoDB的一個例子,我已經使用了兩個ORM庫與Tornado,MotorEngine(https://motorengine.readthedocs.org)和MongoEngine(https://mongoengine-odm.readthedocs.org)。 MongoEngine不使用Tornado IOLoop,因此所有調用都被阻止,MotorEngine使用IOLoop,因此您可以編寫不會阻止的查詢。

還有其他方法可以處理長時間運行的任務(在過去,我已經設置了其他Web服務並使用AsyncHTTPClient來調用它們,我還使用了Celery等任務調度程序將處理推入後臺,通常在另一臺服務器上)。然而,根據我的經驗,數據庫查詢幾乎不是瓶頸,而一個好的經驗法則是儘可能快地確保它們儘可能快,如果你不能希望我的答案有用。

Re。我認爲龍捲風會產生兩個實例並分別將它們從X切換到Y?

龍捲風不產卵多個實例來處理額外的請求,您可以運行龍捲風的多個實例(在我的經驗,每個在龍捲風文檔的例子 - 事實上,這是明智的)。

+0

感謝您的回覆安東尼,有道理,我會尋找與MongoDB使用電機。我想我會把我的編程問題保存到另一個帖子;)乾杯 –

1

Tornado將作爲單線程運行,並在基於套接字事件的請求之間快速切換。如果編寫正確,這是一種處理請求的非常快速的方式,並且是Node.js的工作原理。

但是,您需要確保您的操作在處理請求時處於阻塞狀態,否則將阻止整個線程,從而阻塞整個龍捲風服務器。

您必須只能與異步調用一起使用Tornado。例如,如果您發出http請求,則不能使用傳統的阻止HTTP客戶端。幸運的是龍捲風提供了一個內置的異步庫爲您提供:

http://tornado.readthedocs.org/en/latest/httpclient.html

def handle_request(response): 
    if response.error: 
     print "Error:", response.error 
    else: 
     print response.body 

http_client = AsyncHTTPClient() 

# this line does not block! it immediately returns and you get the result later. 
http_client.fetch("http://www.google.com/", handle_request) 

現在假設X的成效正在阻止持續10秒數據庫寫。

同樣,對於HTTP請求,您的數據庫查詢也不能被阻止。在這種情況下,您將需要使用異步MySQL庫,該庫在您發起請求時立即返回,並在稍後的某個時間返回回調結果。

這是一個潛在的庫中,您可以使用:

https://github.com/PyMySQL/Tornado-MySQL

原因的Node.js是非常受歡迎的這個單線程模式,是因爲原來的Node.js只支持一個線程的最大,所以所有的官方數據庫庫,默認情況下http庫都是異步的。用Python你需要挖掘多個(有時是非官方的)庫來自己找到異步的庫。

編輯:

正如安東尼所說,如果你的數據庫查詢/寫操作快(小於10ms),你應該和作出禁止請求確定。任何結束,你的表現開始受到影響。

+0

感謝您的馬林你的答案充分回答了我的問題。乾杯 –