C ++ Boost.Asio的async_read_until慢 [英] C++ Boost.ASIO async_read_until slow

查看:156
本文介绍了C ++ Boost.Asio的async_read_until慢的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个不寻常的问题。我有一个C ++ Boost.Asio的Web服务器,并处理传入的请求,我用这个code:

I'm having an unusual issue. I have a C++ Boost.ASIO web server, and to handle incoming requests I'm using this code:

boost::asio::async_read_until(
    socket_,
    response_,
    "\r\n\r\n",
    boost::bind(
            &connection::handle_read_headers,
            shared_from_this(),
            boost::asio::placeholders::error,
            boost::asio::placeholders::bytes_transferred
    )
);

(其中socket_是我的boost ::支持ASIO ::知识产权:: TCP ::插座和response_是一个boost :: ASIO ::流缓冲)

(where "socket_" is my boost::asio::ip::tcp::socket and "response_" is a boost::asio::streambuf)

我想只获取请求的报头,然后我后来做了第二次async_read_until与transfer_exactly匹配的是从请求头解析的内容长度。问题是,上述code正在100-900ms一个非常现代的服务器上恢复(从这个读块,直到handle_read_headers()被调用)。传入的​​请求如下:

I'm trying to just grab the headers of the request, then I later do a second async_read_until with transfer_exactly matching the "Content-Length" that was parsed from the request header. The problem is that above code is taking 100-900ms to return on a very modern server (From that read block, until handle_read_headers() is called). The incoming request looks like:

POST /load HTTP/1.1
host: www.mysite.com
Accept: */*
Accept-Encoding: gzip,deflate
Content-type: application/x-www-form-urlencoded
From: googlebot(at)googlebot.com
Origin: http://www.mysite.com
Referer: http://www.mysite.com/another-page/
User-Agent: Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)
X-Forwarded-For: 66.249.75.103
X-Forwarded-Port: 80
X-Forwarded-Proto: http
Content-Length: 287
Connection: keep-alive

and-the-actual-content-is-here.... (287 bytes worth)

标头似乎有\\ r \\ n \\ r \\ n终止,它读取一路EOF(所以它不读整页)前触发handle_read_headers()函数 - 它实际上是跳闸正则表达式。而这些请求都来自谷歌来了,所以我相当有信心它不是他们的最终滞后。

The headers seem to be terminated with a \r\n\r\n, and it does trigger the handle_read_headers() function before reading all the way to EOF (so it's not reading the whole page) - it actually is tripping the regex. And these requests are coming from Google, so I'm quite confident it's not lag on their end.

有什么我可以在它为什么要花这么长的时间来恢复俯瞰?任何其他渔获物aync_read_until我可能会错过?

Is there anything I could be overlooking on why it's taking so long to return? Any other catches with aync_read_until I might have missed?

谢谢!

编辑/ UPDATE:
好了,现在我很困惑。在试图兆字节的建议下,我从一个流缓冲切换到一个字符数组(没有运气),那么我重构我的code使用async_read_some而非async_read_until,只是扫描手动分隔。我还重新设置所有OS变量(sysctrl.conf)骨股票默认值(以缩小的可能性)。不幸的是我仍然看到在以下code 100-900ms延迟从调用具有相同的传入POST请求handle_read():

EDIT/UPDATE: Okay, now I'm very confused. In trying megabyte's suggestion, I switched from a streambuf to a character array (no luck), then I refactored my code to use async_read_some rather than async_read_until, and just scan for the delimited manually. I also reset all OS variables (sysctrl.conf) to bone stock default (to narrow down possibilities). Unfortunately I'm still seeing 100-900ms delays in the following code from calling handle_read() with the same incoming POST request:

socket_.async_read_some(
    boost::asio::buffer(response_),
    boost::bind(
        &connection::handle_read,
        shared_from_this(),
        boost::asio::placeholders::error,
        boost::asio::placeholders::bytes_transferred
    )
);

在哪里response_现在是:

where response_ is now:

boost::array<char, 4096> response_;

要无果(相同100-900ms延迟)。没有办法,这是正常的 - 有什么想法?

To no avail (same 100-900ms delays). There's no way this is normal - any thoughts?

EDIT2:
每Rhashimoto的建议,我启用了处理程序的跟踪,发现这一奇怪现象在日志中:

Per the recommendation of Rhashimoto, I enabled handler tracking and found this oddity in the log:

[2013-07-05 15:58:39 - Thread 7fae57e3f700]: Incoming connection (0ms elapsed)
@asio|1373054319.874916|506*508|socket@0x7fae50004f98.async_receive
@asio|1373054319.874963|506*509|socket@0x7fffd40fed68.async_accept
@asio|1373054319.875008|<506|
@asio|1373054320.609088|>508|ec=system:0,bytes_transferred=512
@asio|1373054320.609233|508*510|socket@0x7fae50004f98.async_receive
@asio|1373054320.609264|<508|
@asio|1373054320.609284|>510|ec=system:0,bytes_transferred=404
[2013-07-05 15:58:40 - Thread 7fae57e3f700]: Received packet headers (638 bytes) - 734ms elapsed

有在async_accept和async_receive之间超过700毫秒。在code,从这个块进入(实际上直接从的<一的HTTP服务器2 href=\"http://www.boost.org/doc/libs/1_54_0/doc/html/boost_asio/examples/cpp03_examples.html\">http://www.boost.org/doc/libs/1_54_0/doc/html/boost_asio/examples/cpp03_examples.html - server.cpp和connection.cpp):

There are over 700 milliseconds between the async_accept and async_receive. In the code, it goes from this block (virtually straight from the "HTTP Server 2" of http://www.boost.org/doc/libs/1_54_0/doc/html/boost_asio/examples/cpp03_examples.html - server.cpp and connection.cpp):

new_connection_->start();
new_connection_.reset(new connection(
        io_service_pool_.get_io_service()
));
acceptor_.async_accept(
        new_connection_->socket(),
        boost::bind(
                &server::handle_accept,
                this,
                boost::asio::placeholders::error
        )
);

从一开始()为:

and from the start() to:

void connection::start()
{
    boost::asio::async_read_until(
        socket_,
        response_,
        "\r\n\r\n",
        boost::bind(
            &connection::handle_read_headers,
            shared_from_this(),
            boost::asio::placeholders::error,
            boost::asio::placeholders::bytes_transferred
        )
    );
}

和时handle_read_headers()被调用时,700毫秒过去了。

and when handle_read_headers() is called, 700ms have passed.

有没有人有什么想法?我完全失去了。

Does anyone have ANY ideas? I'm completely lost.

太感谢了!

推荐答案

让我们看一下处理程序日志

Lets look at the handlers log

[2013-07-05 15:58:39 - Thread 7fae57e3f700]: Incoming connection (0ms elapsed)
@asio|1373054319.874916|506*508|socket@0x7fae50004f98.async_receive
@asio|1373054319.874963|506*509|socket@0x7fffd40fed68.async_accept
@asio|1373054319.875008|<506|
@asio|1373054320.609088|>508|ec=system:0,bytes_transferred=512
@asio|1373054320.609233|508*510|socket@0x7fae50004f98.async_receive
@asio|1373054320.609264|<508|
@asio|1373054320.609284|>510|ec=system:0,bytes_transferred=404
[2013-07-05 15:58:40 - Thread 7fae57e3f700]: Received packet headers (638 bytes) - 734ms elapsed

从日志中我们可以看到 async_receive 被调用了两次:处理程序设置(#506)后,首先是所谓的(#508)734ms。现在,第二个 async_receive 的处理程序设置(#508)后53微秒叫(#510)。这就是它,第二个处理程序调用被解雇blasingly快,因为数据(这些404字节)已经在TCP协议栈准备好了。

From log we can see async_receive is called twice: first is called(#508) 734ms after handler setup(#506). Now, second async_receive is called(#510) 53 microseconds after handler setup(#508). Thats it, second handler call was fired blasingly fast because the data (those 404 bytes) was already ready in TCP stack.

结论:这是不是一个处理程序呼叫时延,这是运输延迟。与ISP或平衡器,或者谷歌可能麻烦真的不希望与要求,并设置延时打扰你。

Conclusion: it is not a handler call delay, it is transport delay. Probably trouble with the ISP or a balancer, or maybe Google really dont want to bother you with requests and setting up delays.

UPD:我觉得你可以用的tcpdump

UPD: I think you can check this with tcpdump

P.S。我不喜欢 io_service_pool _ 从HTTP服务器2示例实现。这可能会导致一些问题,但我却认为它不是当前的情况。

P.S. I dont like io_service_pool_ implementation from HTTP server 2 example. This can cause some problems too, but i think its not current case.

这篇关于C ++ Boost.Asio的async_read_until慢的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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