Flask, Tornado, GEvent, 以及它们的结合的性能比较

Python Web框架性能对比
本文通过实际测试对比了Flask、Tornado及结合Gevent的性能表现。结果显示Tornado在请求处理速度上明显优于Flask,而Gevent的加入虽能提升Tornado的性能但效果有限。

英文: http://blog.wensheng.com/2011/10/performance-of-flask-tornado-gevent-and.html

我在选一个python的互联网框架, 本来已经定下来用Tornado了.  但我还听到很多人推荐Flask的简单性和灵活性, 还有gevent的高性能, 所以决定也试试它们以及它们和Tornado的结合.  我的示例就比”Hello World”应用稍微复杂一点儿, 它用到了模板.  下面是代码:

1, 纯粹Flask (pure_flask.py)

from flask import Flask, render_template
app = Flask(__name__)
@app.route('/')
def main_handler():
    return render_template('main_j2.html', messages="whatever",title="home")
if __name__ == '__main__':
    app.run(port=8888, debug=False)

2, 纯粹Tornado (pure_tornado.py)

import os.path
import tornado.ioloop
import tornado.web

class MainHandler(tornado.web.RequestHandler):
    def get(self):
        self.render('main.html', page_title="", body_id="", messages="whatever",title="home")

settings = {
    "static_path":os.path.join(os.path.dirname(__file__),'static'),
    "template_path":"templates",
}
application = tornado.web.Application([
    (r"/", MainHandler),
], **settings)

if __name__ == "__main__":
    application.listen(8888)
    tornado.ioloop.IOLoop.instance().start()

3, Flask应用运行在Gevent上 (gevent_flask.py)

from gevent.wsgi import WSGIServer
from pure_flask import app
http_server = WSGIServer(('', 8888), app)
http_server.serve_forever()

4, Flask应用运行在Tornado上 (tornado_flask.py)

from tornado.wsgi import WSGIContainer
from tornado.httpserver import HTTPServer
from tornado.ioloop import IOLoop
from pure_flask import app
http_server = HTTPServer(WSGIContainer(app))
http_server.listen(8888)
IOLoop.instance().start()

5, Tornado应用运行在Gevent上 (gevent_tornado.py)

import tornado.wsgi
import gevent.wsgi
import pure_tornado

application = tornado.wsgi.WSGIApplication([
    (r"/", pure_tornado.MainHandler),
],**pure_tornado.settings)

if __name__ == "__main__":
    server = gevent.wsgi.WSGIServer(('', 8888), application)
    server.serve_forever()

程序用到了三个模板文件: main.html, layout.html, and form.html. 主程序只调用了main.html.  main.html扩展(“extends”)了 layout.html, 并包含(“include”)了 form.html. 三个模板文件加起来有30kB大小.

Flask和Tornado用了不同的模板文件(Tornado是main.html, Flask是main_j2.html), 这是因为Flask和Tornado的模板语法虽然相似, 但有些地方不一样.  比如Flask(用Jinja2)模板的”block”用”{% endblock %}”表示结束, “for”用”{% endfor %}”; 但是Tornado模板则只用”{% end %}”.

我用ApacheBench测了这五个的requests per second:

ab -n 1000 -c 4 http://localhost:8888/

每个测五次. 我的机型是6年老的双核Opteron 254服务器.

下面是结果:

pure_flask: 82 88 107 102 71
pure_tornado: 144 244 241 294 290
gevent_flask: 127 139 145 152 110
tornado_flask: 110 88 74 92 101
gevent_tornado: 328 555 177 273 153

五次平均:

pure_flask: 90
pure_tornado: 242
gevent_flask: 135
tornado_flask: 93
gevent_tornado: 297

从上面结果可能看出Tornado比Flask快很多. 而Gevent可以让Tornado更快一些, 但快不了很多.

最终我还是喜欢Tornado应用的简单明了, 用Flask写稍微大一点的应用比较繁琐(比如要使用蓝图-blueprints等), 所以还是决定使用Tornado了.

转载于:https://my.oschina.net/mickelfeng/blog/879644

<think>好的,我现在需要回答用户关于FlaskTornado关系的问题。首先,我得回忆一下这两个框架的基本信息。Flask是一个轻量级的Web框架,主要用于快速构建简单的Web应用,而Tornado则是一个异步的网络库Web框架,适合处理长连接高并发场景。 用户可能想知道它们的区别各自适用的情况,或者是否有互补性。我需要明确两者的定位,然后比较它们的核心特性,比如处理请求的方式、性能、适用场景等。 接下来,我应该考虑用户可能的实际应用场景。比如,是否需要同时使用两者,或者在不同项目中选择哪一个。可能需要举例说明何时用Flask,何时用Tornado,或者如何结合使用,比如用Flask处理常规请求,Tornado处理WebSocket。 还要注意避免技术术语过于复杂,保持解释的易懂性。同时,检查是否有常见的误解需要澄清,比如是否Tornado完全替代Flask,或者两者是否可以整合。 最后,确保回答结构清晰,分点说明两者的关系,可能包括对比、结合使用的方法,以及各自的优缺点。需要验证信息的准确性,比如确认Tornado的异步特性确实适合高并发,而Flask的同步模型更适合常规应用。</think>### FlaskTornado 的关系解析 **Flask** **Tornado** 都是 Python 的 Web 开发框架,但设计目标适用场景有显著差异。以下是两者的核心对比及关系说明: --- #### 一、核心定位对比 | **特性** | **Flask** | **Tornado** | |----------------|------------------------------------|--------------------------------------| | **类型** | 同步 Web 框架 | 异步网络库 + Web 框架 | | **核心目标** | 快速构建简单 Web 应用或 API | 高并发、长连接(如 WebSocket)场景 | | **性能** | 适合低并发常规请求 | 单线程异步 I/O,支持数万并发连接 | | **依赖** | 轻量级,需手动扩展功能 | 内置异步 HTTP 服务器网络工具 | --- #### 二、工作原理差异 1. **Flask 的同步模型** - 基于 WSGI 协议,每个请求占用一个线程/进程。 - **示例代码**: ```python from flask import Flask app = Flask(__name__) @app.route('/') def home(): return "Hello Flask!" if __name__ == '__main__': app.run() # 默认同步服务器(如 Werkzeug) ``` 2. **Tornado 的异步模型** - 使用非阻塞 I/O 事件循环,单线程处理大量并发。 - **示例代码**: ```python import tornado.ioloop import tornado.web class MainHandler(tornado.web.RequestHandler): async def get(self): self.write("Hello Tornado!") def make_app(): return tornado.web.Application([(r"/", MainHandler)]) if __name__ == "__main__": app = make_app() app.listen(8888) tornado.ioloop.IOLoop.current().start() # 启动事件循环 ``` --- #### 三、实际应用中的关系 1. **互补场景** - **Flask**:适合构建 REST API、CMS 等常规 Web 服务。 - **Tornado**:专攻实时通信(如聊天室、股票行情推送)。 - **组合使用案例**: - 用 Flask 处理普通 HTTP 请求(如用户登录)。 - 用 Tornado 处理 WebSocket 长连接(如实时消息推送)。 2. **性能取舍** - **Flask** 在同步模式下,若使用 Gunicorn + Gevent 可部分支持异步,但效率仍低于 Tornado。 - **Tornado** 的异步特性需配合 `async/await` 语法,否则可能阻塞事件循环。 --- #### 四、如何选择? - **选择 Flask 的情况**: - 快速开发小型项目 - 需要大量第三方扩展(如 Flask-SQLAlchemy、Flask-Login) - 团队熟悉传统同步编程模式 - **选择 Tornado 的情况**: - 需要高并发(如在线游戏服务器) - 依赖长轮询或 WebSocket - 自定义底层网络协议(如 TCP/UDP 服务) --- #### 五、整合可能性 通过反向代理(如 Nginx)可将两者部署在同一项目中: ``` 用户请求 → Nginx(路由分发) ├── /api/* → Flask 服务(处理常规 API) └── /ws/* → Tornado 服务(处理 WebSocket) ``` --- ### 总结 Flask Tornado 并非竞争关系,而是针对不同场景的工具。理解其底层模型差异后,可灵活组合使用,兼顾开发效率与性能需求。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值