说明
以下的例子都有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