0. 简介
tornado是一个用Python语言写成的Web服务器兼Web应用框架,由FriendFeed公司在自己的网站FriendFeed中使用,被Facebook收购以后框架以开源软件形式开放给大众。
tornado最大的特点就是其支持异步IO,所以它有着优异的性能。下表是和一些其他Web框架与服务器的对比:(处理器为 AMD Opteron, 主频2.4GHz, 4核) (来源wikipedia)
服务 | 部署 | 请求/每秒 |
---|---|---|
Tornado | nginx, 4进程 | 8213 |
Tornado | 1个单线程进程 | 3353 |
Django | Apache/mod_wsgi | 2223 |
web.py | Apache/mod_wsgi | 2066 |
CherryPy | 独立 | 785 |
先来看看hello world
的例子。^_^
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
import tornado.httpserver import tornado.ioloop import tornado.options import tornado.web from tornado.options import define, options define("port", default=8888, help="run on the given port", type=int) class MainHandler(tornado.web.RequestHandler): def get(self): self.write("Hello, world") def main(): tornado.options.parse_command_line() application = tornado.web.Application([ (r"/", MainHandler), ]) http_server = tornado.httpserver.HTTPServer(application) http_server.listen(options.port) tornado.ioloop.IOLoop.current().start() if __name__ == "__main__": main() |
运行:
1 |
$ python3 helloworld.py |
我们就得到一个web server监听在8888端口。用curl命令get一下,就返回了”Hello, world”。
tornado的代码结构可以在其官网了解,本文着重分析IOLoop的实现。
1. IOLoop
1.1 http交互的大致过程
介绍IOLoop之前我们先看看http server和http client交互的一个大致过程。
server端监听在某个端口,client端发送请求过来,server处理后返回,然后继续等待下一个请求,周而复始。如果用socket那一坨来描述的话就是:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
1. server.py ================================================================ s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.bind(address) s.listen(backlog) While True: connection = s.accept() do_something() connection.send() connection.close() 2. client.py ================================================================= s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect() s.send() s.recv() s.close() |
1.2 聊聊阻塞与非阻塞
所谓阻塞,就是进程正在等待某些资源(如IO),而处于等待运行的状态(不占用CPU资源)。比如connect((“google.com”, 80))返回之前进程都是阻塞的,在它下面的语句得不到执行,除非connect返回。
很显然阻塞式的IO模型有个缺点就是并发量不大,试想如果server进程在do_something()
处阻塞,而这时另外有个客户端试图连进来,则可能得不到响应。
提高并发量有几种实现方式:多线程(一个连接fork一个线程去处理);多进程(一个连接fork一个子进程去处理)(apache);事件驱动(nginx, epoll)等。tornado就是基于epoll(Linux)事件驱动模型实现的。
当然它们有各自的优缺点,此文不详述,有兴趣的读者可以自行google之。^_^
关于IO模型,epoll, 同步,异步,阻塞,非阻塞的概念,可以参考这两篇文章:
https://segmentfault.com/a/11…
http://blog.csdn.net/historya…
1.3 IOLoop实现
1.3.1 IOLoop配置
前文说到tornado是基于epoll事件驱动模型,也不完全正确,tornado实际上是根据平台选择底层驱动。请看IOLoop类的configurable_default
方法:
1 2 3 4 5 6 7 8 9 10 11 |
@class gn: justify">tornado最大的特点就是其支持异步IO,所以它有着优异的性能。下表是和一些其他Web框架与服务器的对比:(处理器为 AMD Opteron, 主频2.4GHz, 4核) (来源wikipedia)
先来看看
运行:
我们就得到一个web server监听在8888端口。用curl命令get一下,就返回了”Hello, world”。 tornado的代码结构可以在其官网了解,本文着重分析IOLoop的实现。 1. IOLoop1.1 http交互的大致过程介绍IOLoop之前我们先看看http server和http client交互的一个大致过程。 server端监听在某个端口,client端发送请求过来,server处理后返回,然后继续等待下一个请求,周而复始。如果用socket那一坨来描述的话就是:
1.2 聊聊阻塞与非阻塞所谓阻塞,就是进程正在等待某些资源(如IO),而处于等待运行的状态(不占用CPU资源)。比如connect((“google.com”, 80))返回之前进程都是阻塞的,在它下面的语句得不到执行,除非connect返回。 很显然阻塞式的IO模型有个缺点就是并发量不大,试想如果server进程在 提高并发量有几种实现方式:多线程(一个连接fork一个线程去处理);多进程(一个连接fork一个子进程去处理)(apache);事件驱动(nginx, epoll)等。tornado就是基于epoll(Linux)事件驱动模型实现的。 当然它们有各自的优缺点,此文不详述,有兴趣的读者可以自行google之。^_^ 关于IO模型,epoll, 同步,异步,阻塞,非阻塞的概念,可以参考这两篇文章: http://blog.csdn.net/historya… 1.3 IOLoop实现1.3.1 IOLoop配置前文说到tornado是基于epoll事件驱动模型,也不完全正确,tornado实际上是根据平台选择底层驱动。请看IOLoop类的
|