原创

Tornado---异步非阻塞(2)

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_34802511/article/details/89399932

例子1:

转载:https://blog.csdn.net/flysky2015/article/details/80034154

两个web服务,服务1和服务2,都是用tornado的框架,有这样一种场景,服务1的a接口里面会请求服务2的c接口,而服务2的c接口又请求服务1的b接口,如果没有加上异步非阻塞,直接请求服务1的a接口会导致两个服务都将陷入卡死状态,无法接受其它请求。

解决方法自然是要用异步的方法来实现,在接口a去请求接口c的过程采用异步库去请求,这样服务1可以继续监听其它请求,所以服务2的c接口请求服务1的b接口就可以正常处理,从而返回结果给a接口。服务1,监听8081端口;服务2,监听8082端口。

当在浏览器输入 192.168.0.120:8081/a 请求服务1的a接口时,进入AHandler的get函数,当遇到yield时,挂起当前get函数,进入get_req函数,然后又遇到yield,挂起当前get_req函数,执行异步请求服务2的c接口,此时服务1不会陷入阻塞状态,仍然可以监听处理其它请求,在服务2的c接口中设置了10秒延时,这个时候去请求服务1的b接口发现是可以正常请求的。不会被阻塞。当服务1的b接口返回时,tornado收到通知从yield出继续执行,完整这个请求。

# !/usr/bin/env python
# coding: utf-8

import tornado.gen
import tornado.web
import tornado.ioloop
from tornado.httpclient import AsyncHTTPClient


@tornado.gen.coroutine
def get_res():
    print "get_res被调用了======>"
    http_client = AsyncHTTPClient()
    response = yield http_client.fetch('http://127.0.0.1:8082/c')
    print "get_res======>", response.body
    # 返回值需要使用 raise gen.Return() 当做异常抛出,因为在 Python 3.2 之前生成器是不允许有返回值的
    raise tornado.gen.Return(response.body)


class AHandler(tornado.web.RequestHandler):
    @tornado.gen.coroutine
    def get(self):
        print "AHandler被调用了======>"
        result = yield get_res()
        print "result======>",result
        self.write(result)


class BHandler(tornado.web.RequestHandler):
    def get(self):
        print "BHandler被调用了======>"
        self.write('调用8080的BHandler')


if __name__ == '__main__':
    app = tornado.web.Application([(r'/a', AHandler), (r'/b', BHandler)])
    app.listen(8080)
    tornado.ioloop.IOLoop.current().start()
# !/usr/bin/env python
#  coding: utf-8

import tornado.web
import tornado.ioloop
import time
import requests


class CHander(tornado.web.RequestHandler):
    def get(self):
        print "CHandler被调用了======>"
        time.sleep(10)
        response = requests.get('http://127.0.0.1:8080/b')
        print response.text
        self.write(response.text)


if __name__ == '__main__':
    app = tornado.web.Application([(r'/c', CHander)])
    app.listen(8082)
    tornado.ioloop.IOLoop.current().start()

例子2:

转载: https://blog.csdn.net/u013038616/article/details/72821600

import time
import tornado.ioloop
import tornado.web
import tornado.options
from tornado import gen

tornado.options.parse_command_line()

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


class NoBlockingHnadler(tornado.web.RequestHandler):
    @gen.coroutine
    def get(self):
        yield gen.sleep(6)
        self.write('NoBlocking Request')


class BlockingHnadler(tornado.web.RequestHandler):
    def get(self):
        time.sleep(6)
        self.write('Blocking Request')


def make_app():
    return tornado.web.Application([
        (r"/", MainHandler),
        (r"/block", BlockingHnadler),
        (r"/noblock", NoBlockingHnadler),
    ], autoreload=True)


if __name__ == "__main__":
    app = make_app()
    app.listen(8003)
    tornado.ioloop.IOLoop.current().start()

 

文章最后发布于: 2019-04-19 14:43:20
展开阅读全文
0 个人打赏

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 技术黑板 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览