tornado HTTPClient 和 gen 模块的实际区别

KJ
  • 1.1k

刚刚在看tornado的gen模块http://www.tornadoweb.org/documentati...

class AsyncHandler(RequestHandler):
    @asynchronous
    def get(self):
        http_client = AsyncHTTPClient()
        http_client.fetch("http://example.com",
                          callback=self.on_fetch)

    def on_fetch(self, response):
        do_something_with_response(response)
        self.render("template.html")

可以用gen模块优化成

class GenAsyncHandler(RequestHandler):
    @asynchronous
    @gen.engine
    def get(self):
        http_client = AsyncHTTPClient()
        response = yield gen.Task(http_client.fetch, "http://example.com")
        do_something_with_response(response)
        self.render("template.html")

ok, 现在书抄完了, 开始提问

我使用 tornado.httpclient.HTTPClient

http_client = httpclient.HTTPClient()
try:
    response = http_client.fetch("http://www.google.com/")
    print response.body
except httpclient.HTTPError, e:
    print "Error:", e

也可以实现同步的代码风格, 实际上应该也是异步执行, 因为用到了IOLoop

我的问题是
1. tornado.httpclient.HTTPClient 用在生产环境有问题嘛?
2. 两种写法达到的效果是不是一样的, 如果不一样, 有什么区别?

回复
阅读 10.4k
3 个回答
✓ 已被采纳

http_client = AsyncHTTPClient()
这个是异步非阻塞的 http_client, 这种方法需要提供 callback ,或用 gen 修饰

http_client = httpclient.HTTPClient()
这个同步阻塞的 http_client, 这个完全就是同步的。。。

参见 http://www.tornadoweb.org/documentati...

答案:
1、用在生产环境完全没问题,前提是你不在乎是不是阻塞的。
2、两种方法,一个是阻塞一个是非阻塞。

outlier
  • 1
新手上路,请多包涵

你这种写法的run起来当然是没有问题的.

但是httpclient.HTTPClient()是blocking的,而Tornado是单进程单线程的,你这样部署在生产环境,一旦有个request向外发起http请求,因为这个向外发起的http请求是blocking的,整个进程会因此block住,后续所有的请求都会被挂起,直到你这个httpclient response.

所以可用性会很差.
答案:
1.用在生产环境绝对会有问题.
2.一个是同步一个是no-blocking.

P.S. Tornado是一个No-blocking的synchronous web server,而非纯asynchronous web server.

很多人混淆这一点. no-blocking真不是异步,,no-blocking的原理就是io的时候进程不断的主动询问kernel数据ready了没有,数据ready了no-blocking从kernel会执行recvfrom从kernel拷数据,这个时候进程是被block住的.在而异步是不需要进程主动询问,kernel在ready的时候发signal给进程.不需要执行revcfrom.

MickeyNan
  • 3
新手上路,请多包涵

上面两位说的不错。
http_client = httpclient.HTTPClient()这个代码实际上为同步阻塞的方式。
而http_client = AsyncHTTPClient() 这样才是Tornado所标榜的异步方式,这个方式需要@gen.coroutine修饰(目前使用的是tornado4.0,代替了以前的gen.engine,这个在官方文档上有说明)。
你提到的同步方式当然可以运行,只不过是以同步阻塞的方式进行,这个实际上可以说是Tornado的一种设计吧,这种方式有其对应的危害,如果在这一步阻塞住了,那么tornado服务器就会阻塞而不能进行任何工作。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
你知道吗?

宣传栏