高并发处理框架-Tornado入门

高并发处理框架-Tornado入门

简介

Tornado是高性能并发框架。适合做api服务。并且他内置的http服务器足够强大,可直接用于生产环境中。

安装

简单地通过pip install tornado即可安装。

协程的使用。

调用方式

在tornado中,协程通过下面三种方式调用:

  1. 在本身是协程的函数内通过yield关键字调用。
  2. 在IOLoop尚未启动时,通过IOLoop的run_sync()函数调用。(run_sync会帮助你完成启动IOLoop,执行函数调用和关闭IOLoop的工作)
  3. 在IOLoop已经启动时,通过IOLoop的spawn_callback()函数调用。(无返回值。只适合不需要返回值的函数使用)

防止阻塞

为防止在协程中调用了阻塞函数,从而导致性能下降。可以在协程中用线程池。

from concurrent.futures import ThreadPoolExecutor

thread_pool = ThreadPoolExecutor(2)

def mySleep(count):
    import time
    for i in range(count):
        time.sleep(1)

@gen.coroutine
def call_blocking():
    print("start of call blocking")
    yield thread_pool.submit(mySleep, 10)
    print("end of call_blocking")

在协和中等待多个异步调用

把这些调用组织成list/dict传给yield即可。

如下所示:

from tornado import gen
from tornado.httpclient import AsyncHTTPClient

@gen.coroutine
def coroutine_visit():
    http_client = AsyncHTTPClient()
    dict_response = yield {
        "baidu":http_client.fetch("www.baidu.com"),
        "sina":http_client.fetch("www.sina.com"),
        "163":http_client.fetch("www.163.com"),
        "google":http_client.fetch("www.google.com"),
        }
    print(dict_response['sina'].body)

Tornado开发介绍

helloword app

三步曲:
1. 创建app
2. 监听端口
3. 启动事件循环。

完整代码如下:

import tornado.ioloop #事件循环
import tornado.web #基本控件

class MainHandler(tornado.web.RequestHandler):
    def get(self):
        self.write("Hello world")

def main():
    app = tornado.web.Application([r"/", MainHandler]) #数组里是定义路由
    app.listen(8888)
    tornado.ioloop.IOLoop.current().start()

if __name__ == '__main__':
    main()

在这里测试了下。在我的macbook(2核+8G内存)下。python+tornado在请求100次,并发10的情况下每秒处理请求数是833
而php7+yii2是37。同样只是简单地输出”hello world”。

路由

路由配置没啥好说的,都一样。字符串/正则。其中需要提取的需要用()分组。

RequestHandler

这个是重点。

请求前,请求后等处理

可以直接参考源码。这里做个大概介绍。
请求前会调用prepare方法。
请求后会调用on_finish方法。
如果需要其它参数,譬如数据库。可以通过配置路由时,再传一个字典参数。

restfulApi

感觉完全是为这个而生的呀。
直接重写RequestHandler相应的方法即可。(get/head/post/delete/patch/put/options)
关于restfulapi可以参考.

获取参数

有两种参数,一种是get请求的,在url中。另一种是post请求的。在Body里面。
get_argument()/get_arguments() 是综合了两种。
get_query_argument()/get_query_arguments() 是url中的。
get_body_argument()/get_body_arguments() 是body中的。
说明下。下面带s的是用于获取数组的。
get_cookie() 获取cookie
request属性可以获取其它信息,如请求方的ip地址,host, method, uri, path,query,headers, body,cookies等。
其中如果发起方用的是json格式的数据,这里要用到body,而上面的3对argument方法无效。

响应

set_status() 设置状态码
set_header()/add_header() 设置http头信息
write()直接输出。当参数是字典时,自动转成json格式,并且Content_Type也会设置成application/json
render()渲染tempalte后输出。
redirect()重定向。

改变同步代码

  1. 异步化:针对RequestHandler的处理函数使用@tornado.web.asynchronous修饰器。
  2. 协程化:针对RequestHandler的处理函数使用@ado.gen.coroutine修饰器,将默认的同步机制改为协程机制。
Tags: