为什么龙卷风中的asynchttpclient不会立即发送请求?

时间:2014-12-30 11:24:59

标签: python tornado nonblocking asynchttpclient

有一次,我需要花很多时间来提交一个非阻塞请求,并且需要2秒钟,龙卷风写一个例子,帮助我!

我在python中有一个使用Tornado的服务器客户端程序。

Server.py:

import tornado.httpserver
import tornado.ioloop
import random
import time

def handle_request(request):
    t = random.randint(1, 10) / 10.
    _str = "%s rep_time: %s delay %s" % (request.body, time.time(), t)
    time.sleep(t)
    request.write('HTTP/1.1 200 OK\r\nContent-Length: %s\r\n\r\n%s' % (len(_str), _str))
    request.finish()

http_server = tornado.httpserver.HTTPServer(handle_request)
http_server.listen(8888)
print "server start..."
tornado.ioloop.IOLoop.instance().start()

client.py:

# -*- coding: utf-8 -*-
from tornado.httpclient import AsyncHTTPClient, HTTPRequest
import tornado.ioloop
import time
from tornado.log import gen_log
from tornado import gen
from tornado.options import parse_command_line
import datetime

@gen.coroutine
def handle_requst(response):
    if response.body:
        gen_log.info("response body: %s" % response.body)

@gen.coroutine
def send_request(num):
    yield AsyncHTTPClient().fetch("http://localhost:8888", handle_requst, method="POST", body="req_time: %s no.: %s" % (time.time(), num))

@gen.coroutine
def run():
    begin_time = int(time.time() + 1)
    while True:
        yield gen.Task(tornado.ioloop.IOLoop.current().add_timeout, datetime.timedelta(seconds=1))
        now_time = int(time.time())

        if now_time == begin_time: 
            gen_log.info('begin_time:%s' % time.time())
            num = 0
            while True:
                num = num + 1
                if num < 10:
                    #Begin submitting data
                    send_request(num)
                # Submit two seconds
                if time.time() > (begin_time + 2):
                    break
            break
    gen_log.info('end_time:%s' % time.time())

if __name__ == '__main__':
    parse_command_line()
    tornado.ioloop.IOLoop.instance().add_callback(run)
    tornado.ioloop.IOLoop.instance().start()

结果

[I 141230 19:05:32 2:24] begin_time:1419937532.08
[I 141230 19:05:34 2:36] end_time:1419937534.0
[I 141230 19:05:34 2:11] response body: req_time: 1419937532.1 no.: 1 rep_time: 1419937534.0 delay 0.1

开始时间:32s
结束时间:34s
请求时间:32s
服务器接受时间:34s

正如您所看到的,服务器接受时间是34秒,我希望服务器接受时间大约为32秒

2 个答案:

答案 0 :(得分:0)

首先,我没有安装龙卷风来检查,但是如果你改变了

yield AsyncHTTPClient().fetch("http://localhost:8888", handle_requst, method="POST", body="req_time: %s no.: %s" % (time.time(), num))

为:

AsyncHTTPClient().fetch("http://localhost:8888", handle_requst, method="POST", body="req_time: %s no.: %s" % (time.time(), num))

我认为你会得到更多的预期(第一个请求立即发送,而不是等待run()方法中断 - 大约需要2秒)。

其次,你正在进行精确的时间比较(如果是now_time == begin_time :)则为fx,在这个例子中你将舍入为int,这样它至少会工作一些时间。但是使用这样的技术会使你的程序最终爆炸。计算机时钟的时间并不像你想象的那么精确,有许多进程在运行,睡眠(0.1)可能超过0.1秒。

第三,您似乎希望您的系统能够与网卡进行即时通信,这种情况不会发生。

第四,你记录为begin_time的不是变量begin_time,你在等待你在服务器中施加的延迟之前保存rep_time,不确定这是否是预期的。

答案 1 :(得分:0)

time.sleep阻止IOLoop,它不允许运行任何其他内容(包括AsyncHTTPClient)。要使龙卷风顺利运行,您必须使用非阻塞等效项替换所有阻止函数(例如,yield gen.Task(IOLoop.current().add_timeout, datetime.timedelta(seconds=1))而不是time.sleep(1))。