tornado異步編程

 說明

如下的例子都有2個url,一個是耗時的請求,一個是能夠馬上返回的請求,,咱們但願的是訪問馬上返回結果的請求不會被其餘耗時請求影響python

非異步處理

如今咱們請求sleep而後同時請求justnow,發現sleep不執行完,justnow也不會返回結果web

#!/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檢測接口,時間加長了json

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":"\u4e2d\u56fd","province":"\u5317\u4eac","city":"\u5317\u4eac","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併發

相關文章
相關標籤/搜索