我希望以固定的时间间隔向服务器发送GET请求并记录请求和响应时间。这个间隔可以是几十毫秒的量级。 我的第一种方法是使用线程池,如本答案https://stackoverflow.com/a/2635066/2390362中所述。然后,只要时间间隔过去,我就会将一个任务放入队列中,现在是发出请求的时间。虽然这有效,但它似乎不太好。使用Tornado测量响应的时间AsyncHTTPClient
我在另一个回答中遇到了Tornado https://stackoverflow.com/a/25549675/2390362。这对于较重的负载似乎表现得更好。这大致是我如何适应它来做我上面描述的。
import time
from tornado import ioloop, httpclient
from datetime import datetime, timedelta
from functools import partial
i = 0
def handle_request(req_time, log, response):
resp_time = datetime.now()
log.write("%s,\t%s,\t%s,\t%s\n"%(req_time.time(), resp_time.time(), (resp_time - req_time).total_seconds(), response.code))
global i
i -= 1
if i == 0:
ioloop.IOLoop.instance().stop()
def do_intervals():
http_client = httpclient.AsyncHTTPClient()
req_count_limit = 3000
interval = 0.01
url = "http://www.someurl.com/"
global i
with open("log_file.log", 'a') as log:
for job_counter in range(req_count_limit):
i += 1
req_time = datetime.now()
current_callback = partial(handle_request, req_time, log)
http_client.fetch(url.strip(), current_callback, method='GET')
time.sleep(interval)
ioloop.IOLoop.instance().start()
if __name__ == '__main__':
do_intervals()
不过,我注意到,当响应到达的回调函数调用只有所有的请求已发送后执行的,而不是。这使我对响应时间的测量不准确。我刚刚发现了Tornado,并不完全确定那里的代码是如何工作的。有没有办法获得我错过的响应时间,或者这是龙卷风和异步HTTP工作的唯一方式?
由于'收率gen.sleep(间隔)'跳出循环的,我把部分内循环在一个单独的'@ gen.coroutine'功能和用于'gen.sleep ()'。但是,在所有请求被发送后,它似乎仍然在调用处理程序。 –
不,如果你想在循环时以非阻塞的方式睡眠,你真的需要在循环迭代过程中产生gen.sleep(interval)。如果你使用'gen.coroutine'来装饰你的'do_intervals',并按照我的指示进行操作,它就会按你的要求工作。我已经更新了我的答案,以便更清楚。 –
我尝试使用'ioloop.PeriodicCallback'工作,但你的解决方案似乎更好地扩展(我会跳过一些回调)。 PS:我还必须删除'ioloop.IOLoop.instance()。stop()',否则我会得到一个'TimeOutError' –