Tornado是用python写的异步web架构库,几行代码就可以写出httpsever和WebSocket server,它是采用python构建 web服务的几种流行的架构之一。
关于Tornado与Django的区别,网文很多,不再描述,笔者选择Tornado而不是Django的主要原因同样是Django包揽太多,灵活度小,而Tornado比较适合中小性网站(不是从性能上讲),这是笔者应用的领域。
本文不是对tornado的系统说明和介绍,而仅是对其关键点的一些解释和笔者的看法,本文的解释大多来自tornado官网http://www.tornadoweb.org/en/stable/index.html,特此说明。
Tornado的安装比较简单,它是纯python代码,联网安装可用pipinstall tornado完成,或源码下载后,运行python setup.py install完成。
本文的示例在ubunt17.10+python3.6.3下完成。
虽然Tornado是异步web架构,但其缺省的运行方式是单进程单线程,如果处理流程中有一个环节是阻塞的,则整个处理流程的效率就大打折扣了,而文件操作、数据库操作多是同步的(或异步操作难于编写和调试),因此笔者认为多进程的运行方式是Tornado的主要方式。
将Tornado web server多进程运行,可以利用Nginx作代理,然后进行分发,多进程运行后,会话/状态管理是必需的,一般由redis来完成。
因此,如果是比较完整的应用,应安装python, tornado,openssl,nginx和redis。
1. 概述
Tornado是一个异步网络库以及基于此之上的web架构库,因此它包含四个部分:
Tornado虽然支持WSGI,但有限制,本文不涉及与其他应用的集成。
2. Application等类
Application看起来像是参数集合类,在应用启动时初始化,接受大量参数,比如最重要的url路由规则定义,web运行参数等。
HTTPServer类看起来是运行类,它可以将Application作为自己的参数。Application也可以创建HTTPServer并运行。
IOLoop类就是消息循环、分发,是程序真正的阻塞点。
几个类大致的关系如下图,在一个应用中,这几个类构成基本的运行框架,它们都是单实例运行。
3. RequestHandler类
RequestHandler是页面的响应类,也就是业务处理的起点和终点。一般情况下,每个页面对应一个类。按照面向对象的观点,所有页面类应置于某个基类之下,这样所有公共的业务都可在该基类中处理,这个我们自己设计的基类同时也是RequestHandler的子类。
对HTTP request的处理,常用功能大致分为以下几类(也是RequestHandler类函数的分类):
4. 错误处理
如果程序发生可预见的错误,可raise tornado.web.HTTPError来终止处理,RequestHandler.write_error被调用,产生错误信息发送给客户端。在debug模式下,缺省的错误是产生500错误并产生堆栈追踪信息。
通常,我们需要定制错误页版式,此时,需要重写我们自己设计的页面基类(见上面描述)的write_error方法。
如果某个页面需要与通常的错误处理不同,可以raise tornado.web. Finish来终止处理,,此时就不会调用write_error方法,但在raise之前,将需要发送给客户端的内容(特别的错误页)设置好,finish的意思就是结束处理并发送缓存(如果有)。
关于404错误的定制,与上面稍有不同,先定义一个类:
class My404Handler(RequestHandler):
# Override prepare() instead of get() to cover all possible HTTP methods.
def prepare(self):
self.set_status(404)
self.render("404.html")
然后在Application类的设置中,添加default_handler_class=My404Handler即可,凡不能被url路由规则处理的请求,都由My404Handler处理。