使用Flask和Tornado一起?

57

我是Flask的忠实粉丝,部分原因是它简单易用,另一部分原因是它有很多扩展功能。然而,Flask是为WSGI环境设计的,而WSGI不是非阻塞的,因此(我认为)对于某些类型的应用程序来说,它的可扩展性不如Tornado

由于每个框架都有一个URL分发器,会调用一个函数,并且两者都使用Python文件(在Django中,您不需要启动Python文件,但在Flask或Tornado中需要),那么在网站中拥有两个独立的部分是否有意义 - 一个部分使用Tornado运行非阻塞作业,另一个部分使用Flask编写?

如果这是个好主意,那么如何在Flask和Tornado之间共享cookie / session?我会遇到问题吗,因为Flask将使用自己的系统,而Tornado将使用其自己的系统?


1
@TimMcNamara 我不知道为什么我会爱上Flask!这个框架在我开始写第一个教程时就能够正常工作!我花了两个月的时间才理解Django的第一步,只是因为我认为Django是Python,而Python只需要运行文件并查看……但这并不是启动Django项目的方式 ;) - Abdelouahab
2
我稍微修改了你的问题 - 如果我没有完全正确,请告诉我 :-) - Sean Vieira
现在更专业了:D - Abdelouahab
2个回答

91

我觉得我已经解决了50%的问题,但是cookie还没有测试过,不过现在我可以使用Tornado加载Flask应用程序,并将Tornado和Flask混合在一起 :)

首先是flasky.py文件,其中包含Flask应用程序:

from flask import Flask
app = Flask(__name__)

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

然后是 cyclone.py 文件,它将加载Flask应用和Tornado服务器+一个简单的Tornado应用程序,希望没有叫做“cyclone”的模块 ^_^

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()
希望这能帮到想要混合它们的人 :)

6
你如何在Tornado中添加异步方法?你能在Flask路由中使用异步吗? - Merlin
2
我知道Flask是一个微框架。但是Tornado不也是一种类似的微框架吗?只不过它内置了一个强大的HTTP服务器。如果你不需要考虑WSGI“容器”的潜在交换,为什么不直接使用Tornado提供的功能进行开发呢? - Jason
1
Flask很好,因为它有许多扩展,所有东西都可以在Flask上进行扩展,所以不需要重新发明轮子。 @Merlin我认为这不是一条容易的路,Flask使用WSGI,而WSGI不是异步的。 - Abdelouahab Pp
4
这真的可行吗?你最终使用了这个方法,还是只使用了Tornado? - Mittenchops
@AbdelouahabPp,尽管Flask使用WSGI而WSGI不是异步的,但是Tornado可以异步接受连接,然后我们每个请求可以在不同的线程中运行(我不确定),然后我们可以使用异步Tornado代替使用同步worker类的Gunicorn,就像Apache预分配模块一样。 - andy

4

根据12,结合起来的简短答案如下:

from flask import Flask
app = Flask(__name__)

@app.route("/")
def hello():
    return "Hello World!"

if __name__ == "__main__":

    from tornado.wsgi import WSGIContainer
    from tornado.httpserver import HTTPServer
    from tornado.ioloop import IOLoop

    http_server = HTTPServer(WSGIContainer(app))
    http_server.listen(8000)
    IOLoop.instance().start()

请考虑在以下链接 23 中提到的有关性能的警告。


最好只使用Tornado而不是将Flask和Tornado结合在一起。 - Ahmad Yoosofan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接