Tornado开发(一)—— 概述及构成

一.概述

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架构库,因此它包含四个部分:

  • 一套适应web应用开发的框架,以这个架构可很快构建web应用;
  • 涉及web应用的http协议和websocket协议的实现(客户端/服务器端);
  • 非阻塞的异步网络通讯库;
  • 异步操作的协程(coroutine)库。

Tornado虽然支持WSGI,但有限制,本文不涉及与其他应用的集成。

2. Application等类

Application看起来像是参数集合类,在应用启动时初始化,接受大量参数,比如最重要的url路由规则定义,web运行参数等。

HTTPServer类看起来是运行类,它可以将Application作为自己的参数。Application也可以创建HTTPServer并运行。

         IOLoop类就是消息循环、分发,是程序真正的阻塞点。

         几个类大致的关系如下图,在一个应用中,这几个类构成基本的运行框架,它们都是单实例运行。


3. RequestHandler类

RequestHandler是页面的响应类,也就是业务处理的起点和终点。一般情况下,每个页面对应一个类。按照面向对象的观点,所有页面类应置于某个基类之下,这样所有公共的业务都可在该基类中处理,这个我们自己设计的基类同时也是RequestHandler的子类。

对HTTP request的处理,常用功能大致分为以下几类(也是RequestHandler类函数的分类):

  • 对header(包括querystring)的处理:包括若干get和set
  • 对body的处理(POST):对get,可用get_body_argument,对set,实际上就是应答了,可用write,还包括模板的管理
  • 对cookie的处理:包括若干get和set,个人感觉加密方式不常用,用服务器端存储敏感内容可适应大多数场景
  • 转向redirect:跳转redirect

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处理。

没有更多推荐了,返回首页