Я использую Tornado для отправки запросов в быстрой периодической последовательности (каждые 0,1 с или даже 0,01 с) на сервер. Для этого я использую AsyncHttpClient.fetch
с обратным вызовом для обработки ответа. Вот очень простой код, чтобы показать, что я имею в виду:Зачем длительный HTTP-раунд-время останавливает мой Tornado AsyncHttpClient?
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
Когда я тестировал его на локальном сервере, она работает нормально, запросы были отправлены вовремя, время спускоподъемных операций явно минимален. Однако, когда я тестирую его на удаленном сервере с большим временем обратного хода (особенно для более высоких нагрузок запроса), время запроса прерывается несколькими секундами: период ожидания между каждым запросом становится намного большим, чем желаемый период.
Почему? Я думал, что асинхронный код не будет затронут временем округления, так как он не блокируется, ожидая ответа. Есть ли какое-нибудь известное решение?
Как вы называете 'send_request'? И что делает 'current_callback'? Если вы вызываете 'send_request'" parallely "и' current_callback' занимает некоторое значительное время, тогда может случиться, что вы складываете много запросов (так как поездка туда и обратно занимает некоторое время), и когда они возвращаются, они обрабатываются один за другим, замедляя все (в том числе новое планирование запросов) из-за характера одиночного потока. Таким образом, время ожидания увеличивается. – freakish
Так кажется, что это на самом деле ** ** из-за асинхронности (у вас не было бы этой проблемы с потоками). Единственное обходное решение, которое я вижу, это сделать период ожидания короче и ждать снова, если таймаут не достигнут. – freakish
@ freakish, как это связано с асинксом?Я потратил довольно много времени, переходя от потоков к асинхронному, потому что потоки делали намного хуже при больших нагрузках и потребляли много памяти для загрузки. –