我有一个用 Flask 编写的网络服务,包含在WSGIContainer
中,并由 Tornado 使用其FallbackHandler
机制提供服务。 flask webservice中的一个路径运行一个非常长的操作(大约需要5分钟完成),当触发此路由时,阻止对任何路由的每个其他调用,直到操作完成。我该如何解决这个问题?
以下是使用 Tornado 提供 Flask 应用程序的方式:
parse_command_line()
frontend_path = os.path.join(os.path.dirname(__file__),"..","webapp")
rest_app = WSGIContainer(app)
tornado_app = Application(
[
(r"/api/(.*)", FallbackHandler, dict(fallback=rest_app)),
(r"/app/(.*)", StaticFileHandler, dict(path=frontend_path))
]
)
答案 0 :(得分:3)
Tornado的WSGI容器不具有很高的可扩展性,只有在您有特定理由在同一进程中组合WSGI和Tornado应用程序时才能使用它。 Tornado不支持长时间运行的WSGI请求;任何可能需要很长时间的事情都需要使用Tornado的本机异步接口而不是WSGI。
WSGI是一个同步接口,而Tornado的并发模型基于单线程异步执行。这意味着使用Tornado的WSGIContainer运行WSGI应用程序的可伸缩性低于在多线程WSGI服务器(如gunicorn或uwsgi)中运行相同的应用程序。仅当在同一进程中将Tornado和WSGI组合在一起的好处超过降低的可伸缩性时,才使用WSGIContainer。
答案 1 :(得分:1)
您可以考虑使用tornado-threadpool,在这种情况下,您的请求会立即返回,任务将在后台完成。
from thread_pool import in_thread_pool
from flask import flash
@app.route('/wait')
def wait():
time_consuming_task()
flash('Time consuming task running in backround...')
return render_template('index.html')
@in_thread_pool
def time_consuming_task():
import time
time.sleep(5)
答案 2 :(得分:0)