2016-09-22 52 views
0

我正在運行一個簡單的Tornado Flask應用程序,但視圖一次只處理一個請求。我怎樣才能使它處理多個併發請求?Flask和Tornado Applciation不處理多個併發請求

我正在使用的修復程序是fork和使用多個進程來處理請求,但我不喜歡該解決方案。

from flask import Flask 

app = Flask(__name__) 

@app.route('/flask') 
def hello_world(): 
    return 'This comes from Flask ^_^' 

from tornado.wsgi import WSGIContainer 
from tornado.ioloop import IOLoop 
from tornado.web import FallbackHandler, RequestHandler, Application 
from flasky import app 

class MainHandler(RequestHandler): 
    def get(self): 
    self.write("This message comes from Tornado ^_^") 

tr = WSGIContainer(app) 

application = Application([ 
    (r"/tornado", MainHandler), 
    (r".*", FallbackHandler, dict(fallback=tr)), 
]) 

if __name__ == "__main__": 
    application.listen(8000) 
    IOLoop.instance().start() 

回答

3

最直接的答案是,你應該使用專用的WSGI服務器,如uWSGI或Gunicorn,並將其配置爲使用多個工人。不要將龍捲風作爲WSGI服務器。


你的產卵過程的修正是正確的,儘管使用WSGI與Tornado是「正確的」。 WSGI是一個同步協議:一個工作者一次處理一個請求。 Flask不知道Tornado,所以使用協程不能很好地處理它:處理請求同步發生。

Tornado has a big warning in their docs about this exact thing.

WSGI是同步接口,而龍捲風的併發模型基於單線程異步執行。這意味着運行帶有Tornado的WSGIContainer的WSGI應用程序比在多線程WSGI服務器(如gunicornuwsgi)中運行相同應用程序的可擴展性更低。只有在將Tornado和WSGI合併到同一個過程中才能獲得好處的情況下,才能使用WSGIContainer,這個過程大大降低了可伸縮性。

換句話說:處理更多的併發請求與WSGI應用程序,產生更多的工人。工作者的類型也很重要:線程與流程與事件小部件都有折衷。您通過自己創建流程來產生工作人員,但使用WSGI服務器(如uWSGI或Gunicorn)更爲常見。

+0

其實這並不完全正確。 WSGI支持一個協同接口,你可以返回一個* iterable *(這可能是一個生成器),而不是完整的結果。不幸的是,並不是很多中間件都使用這個(我不知道)。 –

+0

@JonasWielicki如果你有更多的信息會很棒,但我認爲你可能會讓人感到困惑。返回一個生成器允許流式響應(Flask支持這個),但是一個worker仍然處理一個響應。 – davidism

+0

問題在於Flask/Werkzeug不知道如何使用Tornado,所以處理請求,運行視圖和產生初始響應的所有事情都發生在Tornado的同步範圍內。 – davidism