加入收藏 | 设为首页 | 会员中心 | 我要投稿 | RSS
您当前的位置:首页 > 教程文章 > Python开发

Tornado 异步框架学习

时间:2014-03-18 19:36:17  来源:  作者:

 Tornado是一个非常优秀的非阻塞的web服务框架。按照功能可以把module划分为:

 
Core web framework:
    web
        Application (Web Application 负责path解析与请求分发,重要的方法'__call__')
        RequestHandler (请求处理基本,重载http verb 处理请求)
    httpserver  (初始化TCPServer 与 路由读写请求)
Asynchronous networking:
    ioloop (调度callback 以及轮询 socket fd,处理相应的读写或者错误事件)
    iostream (异步的读写处理)
    netutil (创建绑定套接字,监听端口,等待链接 )
Other utilities
 
Tornado的异步实现就是建立在ioloop(轮询socket fd 读写事件)和iostream(异步的读写)的基础之上。由于不同的os使用的轮询模型不同,只选出linux内核支持的epoll模型来描述。
We use epoll (Linux) or kqueue (BSD and Mac OS X; requires python 2.6+) if they are available,or else we fall back on select(). If you are implementing a system that needs to handle thousands of simultaneous connections, you should use a system that supports either epoll or queue.
 
最好的学习参考资料就是代码,下面根据框架正常的使用流程,提供一个各个模块和方法的信息图:
 
import tornado.web
import tornado.ioloop
class MainHandler(tornado.web.RequestHandler):
    def get(self):
        return 'Hello World'
application = tornado.web.Application([(r'/', MainHandler),],)
application.listen(8080)
tornado.ioloop.IOLoop.instance().start()
 

2.jpg

3.jpg

TcpServer调用一个非常重要的方法add_accept_handler,把连接回调函数和相应的socket传递进去,最终调用ioloop对象注册socket fd 以及对应的callback操作和事件。同时也是在这里把no-blocking socket与异步的读写通过IOStream连接起来。

4.jpg
在调用IOLoop的 start方法后,IOLoop对象开始循环处理 延迟的数据处理callback 以及timeout callback。最终轮询socket fd处理fd对应的callback方法。start方法处理的self._callback,究竟是什么,在什么时间添加的呢? 等下我们会慢慢的揭开面纱。

假设在self._imol.poll(poll_timeout)时,检测到有一个fd有read事件,即有客户连接,则调用对应的callback方法(TCPServer对象的accept_handler对象。),Accept 连接并且紧跟着创建IOStream对象(根据ssl_options选项确定是否是加密socket)。然后调用handle_stream(由于handle_stream 是在HTTPServer定义,实际上调用的是这里的实现). 创建一个HTTPConnection对象。在HTTPConnection的初始化函数__init__()中,调用IOStream read_until方法开始读取数据。首先判断读取的数据是否已经满足条件,如果不满足则继续从socket缓存读取数据.如果已经满足条件,则调用_run_callback,把相应的处理函数(self._header_callback)append到IOLoop对象中,延迟到下次轮询再进行处理. 官方也给出了这样操作的原因:
        # * Prevents unbounded stack growth when a callback calls an IOLoop operation that immediately runs another callback
        # * Provides a predictable execution context for e.g.  non-reentrant mutexes
        # * Ensures that the try/except in wrapper() is run outside of the application's StackContexts
当下次轮询处理到这个callback时, 执行之前传递_header_callback函数对象, 创建HTTPRequest对象,如果请求信息包含body则处理body数据块, 过程类似header处理. 当解析完header和body(body可选)之后, HTTPConnection对象调用request_callback方法,传递HTTPRequest对象. 这里的request_callback对象即我们之前创建的Application对象,这也是为什么Application要定义__call__方法.__call__方法根据解析到得path和method路由到相应的RequestHandler对象,动态的获取相应的方法对象,调用相应的方法. Response 过程和read差别不大,实际上HTTPRequest对象包含着HTTPConnection对象,最终的写入操作被传递给IOStream的write方法.

通过这篇文章,基本上应该对Tornado web服务的工作有了一个初步的了解. 如果想继续深入,请直接看源码, 毕竟Tornado的源码是非常友好的,很多实现都有很高的参考.
来顶一下
返回首页
返回首页
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表
推荐资讯
在CentOS下搭建Android 开发环境
在CentOS下搭建Androi
轻松搭建属于自己的Ubuntu发行版
轻松搭建属于自己的Ub
利用SUSE Studio 打造自己的个性化Linux发行版
利用SUSE Studio 打造
那些采用PHP技术的IT大企业
那些采用PHP技术的IT大
相关文章
栏目更新
栏目热门