首页 > 代码库 > “Tornado源码解析篇”导读索引

“Tornado源码解析篇”导读索引

最近花了2周时间断断续续地阅读了 Tornado 的源码,写了“Tornado源码解析”这个系列专题。由于写得比较散,这里简单做一个索引与导读。

为什么要选择 Tornado 这个框架?先给大家讲一个小故事:赌王娱乐城

"[web.py inspired the] web framework we use at FriendFeed [and] the webapp framework that ships with App Engine..."

— Brett Taylor, co-founder of FriendFeed and original tech lead on Google App Engine

FriendFeed 创始人用了 web.py 作为他们的框架,然后爱上了web.py 。后来他发现web.py的一些不足,然后就创造了一个很像 web.py 的框架 Tornado,性能会强上一些。

更多关于 Tornado 的细节可以参看专题里面具体小节的内容,下面我们开始导读。

1. 为什么要阅读Tornado的源码?

From: 为什么要阅读Tornado的源码?

Tornado 由前 google 员工开发,代码非常精练,实现也很轻巧,加上清晰的注释和丰富的 demo,我们可以很容易的阅读分析 tornado. 通过阅读 Tornado 的源码,你将学到:

  • 理解 Tornado 的内部实现,使用 tornado 进行 web 开发将更加得心应手。
  • 如何实现一个高性能,非阻塞的 http 服务器。
  • 如何实现一个 web 框架。
  • 各种网络编程的知识,比如 epoll
  • python 编程的绝佳实践

2. 一览众山小

我们先了解 Tornado 的框架组成,才知道哪些部分是核心内容,应该重点看,哪些可以迟些再看。

From: 鸟瞰Tornado框架的设计模型

 

从这个图,我们结合下面看,就知道我们应该读哪些内容了。

1. Core web framework

  • tornado.web — 包含web框架的大部分主要功能,包含RequestHandler和Application两个重要的类
  • tornado.httpserver — 一个无阻塞HTTP服务器的实现
  • tornado.template — 模版系统
  • tornado.escape — HTML,JSON,URLs等的编码解码和一些字符串操作
  • tornado.locale — 国际化支持

2. Asynchronous networking 底层模块

  • tornado.ioloop — 核心的I/O循环
  • tornado.iostream — 对非阻塞式的 socket 的简单封装,以方便常用读写操作
  • tornado.httpclient — 一个无阻塞的HTTP服务器实现
  • tornado.netutil — 一些网络应用的实现,主要实现TCPServer类

3. Integration with other services

  • tornado.auth — 使用OpenId和OAuth进行第三方登录
  • tornado.database — 简单的MySQL服务端封装
  • tornado.platform.twisted — 在Tornado上运行为Twisted实现的代码
  • tornado.websocket — 实现和浏览器的双向通信
  • tornado.wsgi — 与其他python网络框架/服务器的相互操作

4. Utilities

  • tornado.autoreload — 生产环境中自动检查代码更新
  • tornado.gen — 一个基于生成器的接口,使用该模块保证代码异步运行
  • tornado.httputil — 分析HTTP请求内容
  • tornado.options — 解析终端参数
  • tornado.process — 多进程实现的封装
  • tornado.stack_context — 用于异步环境中对回调函数的上下文保存、异常处理
  • tornado.testing — 单元测试

要读哪些内容?

你可以参看这篇文章来了解需要读哪些文件:Tornado源码必须要读的几个核心文件

Core web framework 部分,tornado.web 包含web框架的大部分主要功能,这个需要重点看,它包含RequestHandler和Application两个重要的类。Application 是个单例,总揽全局路由,创建服务器负责监听,并把服务器传回来的请求进行转发(__call__)。RequestHandler 是个功能很丰富的类,基本上 web 开发需要的它都具备了,比如redirect,flush,close,header,cookie,render(模板),xsrf,etag等等。关于这个模块的解析,可以参看以下三篇文章:

  • Tornado RequestHandler和Application类
  • Application对象的接口与起到的作用
  • RequestHandler的分析

接下来是 tornado.httpserver,一个无阻塞HTTP服务器的实现。从 web 跟踪到 httpserver.py 和 tcpserver.py。这两个文件主要是实现 http 协议,解析 header 和 body, 生成request,回调给 appliaction,一个经典意义上的 http 服务器(written in python)。众所周知,这是个很考究性能的一块(IO),所以它和其它很多块都连接到了一起,比如 IOLoop,IOStream,HTTPConnection 等等。这里 HTTPConnection 是实现了 http 协议的部分,它关注 Connection 嘛,这是 http 才有的。至于监听端口,IO事件,读写缓冲区,建立连接之类都是在它的下层--tcp里需要考虑的,所以,tcpserver 才是和它们打交道的地方。关键部分是 HTTP 层与 TCP 层的工作原理:

  • HTTP层:HTTPRequest,HTTPServer与HTTPConnection
  • Tornado在TCP层里的工作机制

剩下的 tornado.template,tornado.escape 之类的可以先不阅读,会使用就行。

接下来是 Asynchronous networking 底层模块,特别是底层的网络模块。

tornado.ioloop 是核心的I/O循环,需要重点看。如果你用过 select/poll/epoll/libevent 的话,对它的处理模型应该相当熟悉。简言之,就是一个大大的循环,循环里等待事件,然后处理事件。这是开发高性能服务器的常见模型,tornado 的异步能力就是在这个类里得到保证的:

  • Tornado高性能的秘密:ioloop对象分析
  • Tornado IOLoop instance()方法的讲解
  • Tornado IOLoop start()里的核心调度
  • Tornado IOLoop与Configurable类

然后是tornado.iostream,对非阻塞式的 socket 的简单封装,以方便常用读写操作。这个也是重要模块。IOStream。顾名思义,就是负责IO的。说到IO,就得提缓冲区和IO事件。缓冲区的处理都在它自个儿类里,IO事件的异步处理就要靠 IOLoop 了:

  • 对socket封装的IOStream机制概览
  • IOStream实现读写的一些细节

如果有兴趣,可以阅读更多源码,比如epoll.py。其实这个文件也没干啥,就是声明了一下服务器使用 epoll。选择 select/poll/epoll/kqueue 其中的一种作为事件分发模型,是在 tornado 里自动根据操作系统的类型而做的选择,所以这几种接口是一样的(当然效率不一样):

  1. 预备知识:我读过的对epoll最好的讲解
  2. epoll与select/poll性能,CPU/内存开销对比

读完这些部分,就可以算是认为读完 Tornado 的核心源码了,当然还有许多许多的其它功能可以读,但是主框架已经读完,其它也就是枝叶部分了。这个专题也会慢慢完善下去,这里仅仅作个阶段性导读。

“Tornado源码解析篇”导读索引