Flask和Tornado Applciation不处理多个并发请求

时间:2016-09-22 16:25:40

标签: python flask tornado

我正在使用Tornado运行一个简单的Flask应用程序,但视图一次只处理一个请求。如何让它处理多个并发请求?

我使用的修复是分叉并使用多个进程来处理请求,但我不喜欢这个解决方案。

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()

1 个答案:

答案 0 :(得分:3)

直接的答案是您应该使用专用的WSGI服务器,例如uWSGI或Gunicorn,并将其配置为使用多个工作程序。不要将Tornado作为WSGI服务器。

您对产卵过程的修复是正确的,因为使用带有Tornado的WSGI是“正确的”。 WSGI是一种同步协议:一个工作者一次处理一个请求。 Flask不知道Tornado,因此使用协同程序无法很好地处理它:处理请求同步发生。

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

  

WSGI是一个同步接口,而Tornado的并发模型基于单线程异步执行。这意味着在Tornado的WSGIContainer中运行WSGI应用程序的可伸缩性比在gunicornuwsgi等多线程WSGI服务器中运行相同的应用程序要差。只有在将Tornado和WSGI组合在同一过程中的好处超过降低的可伸缩性时才使用WSGIContainer

换句话说:使用WSGI应用程序处理更多并发请求,会产生更多工作者。工作者的类型也很重要:线程与进程与eventlet都有权衡。您通过自己创建流程来产生工作者,但使用WSGI服务器(如uWSGI或Gunicorn)更为常见。