Tornado中异步框架的使用

Posted shenjianping

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Tornado中异步框架的使用相关的知识,希望对你有一定的参考价值。

tornado的同步框架与其他web框架相同都是处理先来的请求,如果先来的请求阻塞,那么后面的请求也会处理不了。一直处于等待过程中。但是请求一旦得到响应,那么:

  • 请求发送过来后,将需要的本站资源直接返回给客户端
  • 请求发送过来后,本站没有需要的资源,从其它站点获取过来,再返回给客户端

一、Tornado中的同步框架

1、本站资源直接返回

import tornado.web
import time
 
class LoginHandler(tornado.web.RequestHandler):
 
    def get(self):
        time.sleep(10) #第一个请求来后等10s,后面的请求无法处理,只有等这个请求结束后才能处理其他的请求
        self.write(LoginHandler)
 
    def post(self):
        pass
 
class IndexHandler(tornado.web.RequestHandler):
 
    def get(self):
        self.write(IndexHandler)
 
    def post(self):
        pass
 
application=tornado.web.Application([
    (r/login/,LoginHandler),
    (r/index/, IndexHandler),
 
],)
 
if __name__ == __main__:
    application.listen(8888)
    tornado.ioloop.IOLoop.instance().start()

可以看到因为回调函数中阻塞了10s,所以后面的请求必须等这个回调函数结束后才能处理后面的请求,在tornado中使用future对象进行异步处理。

2、从其它站点获取资源再返回

import tornado.web
import requests
 
class LoginHandler(tornado.web.RequestHandler):
 
    def get(self):
        requests.get(http://www.baidu.com) #此时无法处理其它请求
        self.write(LoginHandler)
 
    def post(self):
        pass
 
class IndexHandler(tornado.web.RequestHandler):
 
    def get(self):
        self.write(IndexHandler)
 
    def post(self):
        pass
 
application=tornado.web.Application([
    (r/login/,LoginHandler),
    (r/index/, IndexHandler),
 
],)
 
if __name__ == __main__:
    application.listen(8888)
    tornado.ioloop.IOLoop.instance().start()

从其它站点获取资源的过程也是阻塞的,服务端处理不了其它请求,必须等这个请求处理完毕才能处理其它请求。

二、Tornado中的异步框架

对于上面的两种情况tornado也是有对策的,就是使用future对象,进行异步处理。

1、本站资源直接返回

import tornado.web
from tornado import gen
from tornado.concurrent import Future
import time
 
class LoginHandler(tornado.web.RequestHandler):
    @gen.coroutine
    def get(self):
        future=Future()
        tornado.ioloop.IOLoop.current().add_timeout(time.time()+10,self.done) #此处的10s延迟不会影响处理其它请求
        yield future
 
    def done(self,*args,**kwargs):
        self.write(LoginHandler)
        self.finish()
 
    def post(self):
        pass
 
class IndexHandler(tornado.web.RequestHandler):
 
    def get(self):
        self.write(IndexHandler)
 
    def post(self):
        pass
 
application=tornado.web.Application([
    (r/login/,LoginHandler),
    (r/index/, IndexHandler),
 
],)
 
if __name__ == __main__:
    application.listen(8888)
    tornado.ioloop.IOLoop.instance().start()

2、从其它站点获取资源再返回

import tornado.web
from tornado import gen
from tornado import httpclient
 
class LoginHandler(tornado.web.RequestHandler):
 
    @gen.coroutine
    def get(self):
        http=httpclient.AsyncHTTPClient()
        yield http.fetch(http://www.google.com,self.done) #访问其它网址不能用requests,应该使用tornado内置的,其实质也是返回future对象
 
    def done(self,*args,**kwargs):
 
        self.write(LoginHandler)
        self.finish()
 
 
    def post(self):
        pass
 
class IndexHandler(tornado.web.RequestHandler):
 
    def get(self):
        self.write(IndexHandler)
 
    def post(self):
        pass
 
application=tornado.web.Application([
    (r/login/,LoginHandler),
    (r/index/, IndexHandler),
 
],)
 
if __name__ == __main__:
    application.listen(8888)
    tornado.ioloop.IOLoop.instance().start()

  tornado解决异步请求就是利用future对象。future对象中设定默认参数result=None,如果在某一时刻future的result中被设定值了,那么它就会自动执行回调函数,实际上这种执行回调函数的功能就是所谓的异步,不需要服务器等待,自己自动执行完后会进行回调(注意这都是在一个线程中)。详情参考:https://www.cnblogs.com/shenjianping/p/11622210.html

 

以上是关于Tornado中异步框架的使用的主要内容,如果未能解决你的问题,请参考以下文章

Tornado----自定义异步非阻塞Web框架:Snow

Python web框架 Tornado异步非阻塞

Tornado异步非阻塞的使用以及原理

对Tornado异步操作Sqlalchemy方法的选定 不错

Python 使用 Tornado Web 框架写HTTP接口实例代码(异步+线程池)

Tornado 线程池应用