为什么长HTTP往返时间会拖延我的Tornado AsyncHttpClient? [英] Why do long HTTP round trip-times stall my Tornado AsyncHttpClient?

查看:735
本文介绍了为什么长HTTP往返时间会拖延我的Tornado AsyncHttpClient?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用Tornado以快速,定期的连续(每0.1秒甚至0.01秒)向服务器发送请求。为此,我使用 AsyncHttpClient.fetch 并使用回调来处理响应。
这是一个非常简单的代码来显示我的意思:

I'm using Tornado to send requests in rapid, periodic succession (every 0.1s or even 0.01s) to a server. For this, I'm using AsyncHttpClient.fetch with a callback to handle the response. Here's a very simple code to show what I mean:

from functools import partial
from tornado import gen, locks, httpclient
from datetime import timedelta, datetime

    # usually many of these running on the same thread, maybe requesting the same server
 @gen.coroutine
 def send_request(url, interval):
    wakeup_condition = locks.Condition()
    #using this to allow requests to send immediately
    http_client = httpclient.AsyncHTTPClient(max_clients=1000) 

    for i in range(300):
        req_time = datetime.now()

        current_callback = partial(handle_response, req_time)
        http_client.fetch(url, current_callback, method='GET')
        yield wakeup_condition.wait(timeout=timedelta(seconds=interval))

def handle_response(req_time,  response):
    resp_time = datetime.now()
    write_to_log(req_time, resp_time, resp_time - req_time) #opens the log and writes to it

当我在本地服务器上测试时,它工作正常,请求按时发送,往返时间明显最小。
然而,当我针对远程服务器测试它时,往返时间较长(特别是对于更高的请求负载),请求时间被搞砸多秒:每个请求之间的等待时间变得比期望的时期。

When I was testing it against a local server, it was working fine, the requests were being sent on time, the round trip time was obviously minimal. However, when I test it against a remote server, with larger round trip times (especially for higher request loads), the request timing gets messed up by multiple seconds: The period of wait between each request becomes much larger than the desired period.

为什么?我认为异步代码不会受到往返时间的影响,因为它在等待响应时没有阻塞。有没有任何已知的解决方案?

How come? I thought the async code wouldn't be affected by the roundtrip time since it isn't blocking while waiting for the response. Is there any known solution to this?

推荐答案

经过一些修补和tcpdumping,我得出结论,两件事情真的在减慢我的协程。有了这两个纠正的停顿大幅下降,中的超时产生wakeup_condition.wait(超时= timedelta(秒=间隔))受到更好的尊重:

After some tinkering and tcpdumping, I've concluded that two things were really slowing down my coroutine. With these two corrected stalling has gone down enormously drastically and the timeout in yield wakeup_condition.wait(timeout=timedelta(seconds=interval)) is much better respected:


  1. 我正在运行的计算机似乎没有缓存DNS,对于AsyncHTTPClient似乎是一个阻塞的网络电话。因此,每个协同程序发送请求都有额外的时间等待DNS解析。 Tornado文档说:




tornado.httpclient在DNS
分辨率的默认配置块中但是不在其他网络访问(缓解此使用
ThreadedResolver tornado.curl_httpclient
正确配置的 libcurl 的构建。

...和在 AsynHTTPClient docs


要选择curl_httpclient,请在启动时调用AsyncHTTPClient.configure:

To select curl_httpclient, call AsyncHTTPClient.configure at startup:

AsyncHTTPClient.configure(tornado。 curl_httpclient.CurlAsyncHTTPClient)

我最终实现了自己的线程来解析和缓存DNS,但是,并且通过直接向IP地址发出请求解决了这个问题。

I ended up implementing my own thread which resolves and caches DNS, however, and that resolved the issue by issuing the request directly to the IP address.


  1. 我使用的URL是HTTPS,更改为HTTP网址提高了性能。对于我的用例并非总是可行,但能够本地化部分问题是件好事

这篇关于为什么长HTTP往返时间会拖延我的Tornado AsyncHttpClient?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆