AsyncHTTPClient 是tornado 的异步HTTP 客户端,如果你的服务需要访问其他的API接口,且希望是异步的进行,就必须使用AsyncHTTPClient,requests库虽然应用更广泛,但它本身并不支持异步。这就是人们对tornado理解的一个误区,tornado是一个异步框架,但这不意味你使用tornado开发时所做的每一个事情都是异步的,这依赖于你所使用的库是不是支持异步。
import tornado.ioloop
from tornado.web import RequestHandler, Application
from tornado.httpserver import HTTPServer
from tornado.httpclient import AsyncHTTPClient
from tornado.options import options, define
define('port', default=8000, help='监听端口')
async def asynchronous_fetch(url):
"""
异步发起http请求
:param url:
:return:
"""
http_client = AsyncHTTPClient()
response = await http_client.fetch(url)
return response
class HelloHandler(RequestHandler):
async def get(self):
response = await asynchronous_fetch('http://coolpython.net')
self.write(response.body)
if __name__ == '__main__':
options.parse_command_line()
handlers_routes = [
(r'/', HelloHandler)
]
app = Application(handlers=handlers_routes)
http_server = HTTPServer(app)
http_server.listen(options.port)
tornado.ioloop.IOLoop.current().start()
当用户的请求被HelloHandler 处理时,程序会异步的向coolpython.net发起请求,在实践中,往往是另一个服务提供的API接口,在这个示例中,使用的是我的个人博客。
单从代码来观察,并不能够看出异步与并发之间的关系,假设coolpython.net返回请求需要1秒钟的时间,而我们也没有使用这种异步的http客户端发送请求, 当10个用户同时访问 http://127.0.0.1:8000/ 时,10个用户都获得响应所需要的时间一定是大于等于10秒钟的,发送http请求是一个阻塞的过程,每个请求最少耗时是1秒,10个请求至少耗时10秒。
同样的并发场景下,使用AsyncHTTPClient 发送http请求,由于其异步的特性,尽管单次的请求是1秒钟,但这1秒钟的大部分时间都用在了io等待上,异步的情况下,他们彼此之间不会互相阻塞,这意味着他们几乎同时进入等待状态,因此最后的耗时一定是大于1秒钟小于10秒钟的。
究竟是2秒,还是3秒,主要取决于网络带宽和机器性能,从理论上来说,网络带宽越大,机器性能越好,整体的时间就越接近于1秒钟。
使用tornado开发web服务,想要访问msyql, redis, mongodb 等数据库,同样需要使用专门的支持异步的客户端,否则就无法利用tornado的异步特性,tornado也不适合做CPU 密集型的服务,异步是针对io而言的,对cpu无能为力,此时要考虑多进行部署。
QQ交流群: 211426309