tornado异步编程

 说明

以下的例子都有2个url,一个是耗时的请求,一个是可以立刻返回的请求,,我们希望的是访问立刻返回结果的请求不会被其他耗时请求影响

非异步处理

现在我们请求sleep然后同时请求justnow,发现sleep不执行完,justnow也不会返回结果

#!/bin/env python

import tornado.httpserver
import tornado.ioloop
import tornado.options
import tornado.web
import tornado.httpclient

import time

from tornado.options import define, options
define("port", default=8000, help="run on the given port", type=int)

class SleepHandler(tornado.web.RequestHandler):
    def get(self):
        time.sleep(5)
        self.write("when i sleep 5s")

class JustNowHandler(tornado.web.RequestHandler):
    def get(self):
        self.write("i hope just now see you")

if __name__ == "__main__":
    tornado.options.parse_command_line()
    app = tornado.web.Application(handlers=[
            (r"/sleep", SleepHandler), (r"/justnow", JustNowHandler)])
    http_server = tornado.httpserver.HTTPServer(app)
    http_server.listen(options.port)
    tornado.ioloop.IOLoop.instance().start()

异步处理

#!/bin/env python

import tornado.httpserver
import tornado.ioloop
import tornado.options
import tornado.web
import tornado.httpclient
import tornado.gen
from tornado.concurrent import run_on_executor
# 这个并发库在python3自带在python2需要安装sudo pip install futures
from concurrent.futures import ThreadPoolExecutor

import time

from tornado.options import define, options
define("port", default=8000, help="run on the given port", type=int)

class SleepHandler(tornado.web.RequestHandler):
    executor = ThreadPoolExecutor(2)
    @tornado.web.asynchronous
    @tornado.gen.coroutine
    def get(self):
        # 假如你执行的异步会返回值被继续调用可以这样(只是为了演示),否则直接yield就行
        res = yield self.sleep()
        self.write("when i sleep %s s" % a)
        self.finish()

    @run_on_executor
    def sleep(self):
        time.sleep(5)
        return 5

class JustNowHandler(tornado.web.RequestHandler):
    def get(self):
        self.write("i hope just now see you")

if __name__ == "__main__":
    tornado.options.parse_command_line()
    app = tornado.web.Application(handlers=[
            (r"/sleep", SleepHandler), (r"/justnow", JustNowHandler)])
    http_server = tornado.httpserver.HTTPServer(app)
    http_server.listen(options.port)
    tornado.ioloop.IOLoop.instance().start()

后端异步web请求

import tornado.httpserver
import tornado.ioloop
import tornado.options
import tornado.web
import tornado.httpclient
import tornado.gen
from tornado.concurrent import run_on_executor
# 这个并发库在python3自带在python2需要安装sudo pip install futures
from concurrent.futures import ThreadPoolExecutor

import time
import  json

from tornado.options import define, options
define("port", default=8000, help="run on the given port", type=int)


class IndexHandler(tornado.web.RequestHandler):
    @tornado.web.asynchronous
    @tornado.gen.engine
    def get(self):
        #client=tornado.httpclient.AsyncHTTPClient()
        http = tornado.httpclient.AsyncHTTPClient()
        #response=yield tornado.gen.Task(client.fetch,"http://127.0.0.1:8078/sleep")
        url="http://127.0.0.1:8098/sleep"
        #设置超时时间,如果时间很短可以直接把url 放到fetch(url)内
        req = tornado.httpclient.HTTPRequest(url, request_timeout=3000000)
        response = yield http.fetch(req)
        print(response.body)
        data = json.loads(response.body)
        print(data)
        if 1 == data["ret"]:
            self.write(u"国家:%s 省份: %s 城市: %s" % (data["country"], data["province"], data["city"]))
        else:
            self.write("查询IP信息错误")
        self.finish()

class JustNowHandler(tornado.web.RequestHandler):
    def get(self):
        self.write("i hope just now see you")

if __name__ == "__main__":
    tornado.options.parse_command_line()
    app = tornado.web.Application(handlers=[
            (r"/justnow", JustNowHandler),
            (r"/index", IndexHandler)])
    http_server = tornado.httpserver.HTTPServer(app)
    http_server.listen(options.port)
    tornado.ioloop.IOLoop.instance().start()

被请求的网站

模拟新浪IP检测接口,时间加长了

url:http://127.0.0.1:8078/sleep

import tornado.httpserver
import tornado.ioloop
import tornado.options
import tornado.web
import time



from tornado.options import define, options
define("port", default=8098, help="run on the given port", type=int)

class SleepHandler(tornado.web.RequestHandler):

    def get(self):
        time.sleep(30)
        self.write({"ret":1,"start":-1,"end":-1,"country":"u4e2du56fd","province":"u5317u4eac","city":"u5317u4eac","district":"","isp":"","type":"","desc":""})



if __name__ == "__main__":
    tornado.options.parse_command_line()
    app = tornado.web.Application(handlers=[
            (r"/sleep", SleepHandler)])
    http_server = tornado.httpserver.HTTPServer(app)
    http_server.listen(options.port)
    tornado.ioloop.IOLoop.instance().start()

参考:http://www.tuicool.com/articles/36ZzA3

 

原文地址:https://www.cnblogs.com/xiaoshi657/p/6945208.html