深入理解Tornado——一个异步web服务器
转载请注明出处:http://www.cnblogs.com/yiwenshengmei/archive/2011/06/08/understanding_tornado.html
原文地址:http://golubenco.org/?p=16
这篇文章的目的在于对Tornado这个异步服务器软件的底层进行一番探索。我采用自底向上的方式进行介绍,从轮训开始,向上一直到应用层,指出我认为有趣的部分。
所以,如果你有打算要阅读Tornado这个web框架的源码,又或者是你对一个异步web服务器是如何工作的感兴趣,我可以在这成为你的指导。
通过阅读这篇文章,你将可以:
自己写一个Comet架构程序的服务器端部分,即使你是从拷贝别人的代码开始。如果你想在Tornado框架上做开发,通过这篇文章你将更好的理解Tornado web框架。在Tornado和Twisted的争论上,你将更有见解。介绍假设你还不知道Tornado是什么也不知道为什么应该对它感兴趣,那我将用简短的话来介绍Tornado这个项目。如果你已经对它有了兴趣,你可以跳去看下一节内容。
Tornado是一个用Python编写的异步HTTP服务器,同时也是一个web开发框架。该框架服务于FriendFeed网站,最近Facebook也在使用它。FriendFeed网站有用户数多和应用实时性强的特点,所以性能和可扩展性是很受重视的。由于现在它是开源的了(这得归功于Facebook),我们可以彻底的对它是如何工作的一探究竟。
我觉得对非阻塞式IO (nonblocking IO) 和异步IO (asynchronous IO ?AIO)很有必要谈一谈。如果你已经完全知道他们是什么了,可以跳去看下一节。我尽可能的使用一些例子来说明它们是什么。
让我们假设你正在写一个需要请求一些来自其他服务器上的数据(比如数据库服务,再比如新浪微博的open api)的应用程序,然后呢这些请求将花费一个比较长的时间,假设需要花费5秒钟。大多数的web开发框架中处理请求的代码大概长这样:
?通过上述阅读,我们的介绍已经涵盖了大部分IOLoop模块。正如广告中介绍的那样,它是一段优雅而又简单的代码。
从sockets到流让我们来看看IOStream模块。它的目的是提供一个对非阻塞式sockets的轻量级抽象,它提供了三个方法:
read_until(),从socket中读取直到遇到指定的字符串。这为在读取HTTP头时遇到空行分隔符自动停止提供了方便。read_bytes(),从socket中读取指定数量的字节。这为读取HTTP消息的body部分提供了方便。write(),将指定的buffer写入socket并持续监测直到这个buffer被发送。所有上述的方法都可以通过异步方式在它们完成时触发回调函数。write()方法提供了将调用者提供的数据加以缓冲直到IOLoop调用了它的(指write方法的,译者注)处理器的功能,因为到那时候就说明socket已经为写数据做好了准备:
?将结果写回客户端的工作在HTTPRequest类中处理,你可以在上面的_on_headers()方法中看到具体的实现。HTTPRequest类仅仅将写回的工作代理给了stream对象。
def write(self, chunk): assert self._request, "Request closed" self.stream.write(chunk, self._on_write_complete)?通过这篇文章,我已经涵盖了从socket到应用层的所有方面。这应该能给你关于Tornado是如何工作的一个清晰的理解。总之,我认为Tornado的代码是非常友好的,我希望你也这样认为。
Tornado框架还有很大一部分我们没有探索,比如wep.py(应该是web.py,译者注)这个实际与你应用打交道的模块,又或者是template engine模块。如果我有足够兴趣的话,我也会介绍这些部分。可以通过订阅我的RSS feed来鼓励我。