使用Tornado AsyncHTTPClient测量响应时间

时间:2016-06-21 21:17:00

标签: python python-3.x http tornado

我想以固定的时间间隔向服务器发送GET请求并记录请求和响应时间。该间隔可以是几十毫秒的量级。 我的第一种方法是使用线程池,如本答案https://stackoverflow.com/a/2635066/2390362中所述。然后,每当时间间隔过去并且是时候发出请求时,我会将任务放入队列。虽然这很有效,但它看起来并不太好。

我在另一个答案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()

但是,我注意到回调函数仅在所有请求发送后执行,而不是在响应到达时执行。这使得我对响应时间的测量不准确。我刚发现龙卷风并不完全确定那里的代码是如何工作的。有没有办法获得我错过的响应时间,或者这是龙卷风和异步HTTP工作的唯一方式?

1 个答案:

答案 0 :(得分:0)

handle_request中,可以使用resp_time - req_time合理地衡量请求持续时间。

问题在于您使用time.sleep阻止事件循环,这意味着大多数处理在初始for循环完成之前不会进行。请参阅Why isn’t this example with time.sleep() running in parallel? 尝试类似:

@gen.coroutine
def do_intervals():
    # ... existing code ...
    yield gen.sleep(interval)  # instead of time.sleep

IOLoop.instance().start()移除do_intervals。 像以下一样运行:

IOLoop.instance().run_sync(do_intervals)