我遇到了一个不寻常的问题。我有一个 C++ Boost.ASIO Web 服务器,为了处理传入请求,我使用以下代码:
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::ip::tcp::socket,“response_”是 boost::asio::streambuf)
我试图获取请求的标头,然后我稍后执行第二个 async_read_until ,其传输与从请求标头解析的“内容长度”完全匹配。问题是上面的代码在一个非常现代的服务器上需要 100-900 毫秒才能返回(从该读取块开始,直到调用 handle_read_headers() 为止)。传入的请求如下所示:
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() 函数(因此它不会读取整个页面) - 它实际上是在触发正则表达式。这些请求来自谷歌,所以我非常有信心它不会落后于他们。
为什么要花这么长时间才能回来,有什么我可以忽略的吗?我可能错过了 async_read_until 的其他捕获吗?
Thanks!
编辑/更新:
好吧,现在我很困惑。在尝试兆字节的建议时,我从streambuf切换到字符数组(不走运),然后我重构代码以使用async_read_some而不是async_read_until,然后手动扫描分隔符。我还将所有操作系统变量(sysctrl.conf)重置为默认值(以缩小可能性)。不幸的是,在使用相同的传入 POST 请求调用 handle_read() 时,我仍然在以下代码中看到 100-900 毫秒的延迟:
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_现在是:
boost::array<char, 4096> response_;
无济于事(同样的 100-900 毫秒延迟)。这不可能是正常的——有什么想法吗?
编辑2:
根据 Rhashimoto 的建议,我启用了处理程序跟踪,并在日志中发现了这个奇怪的地方:
[2013-07-05 15:58:39 - Thread 7fae57e3f700]: Incoming connection (0ms elapsed)
@asio|1373054319.874916|506*508|[email protected] /cdn-cgi/l/email-protection_receive
@asio|1373054319.874963|506*509|[email protected] /cdn-cgi/l/email-protection_accept
@asio|1373054319.875008|<506|
@asio|1373054320.609088|>508|ec=system:0,bytes_transferred=512
@asio|1373054320.609233|508*510|[email protected] /cdn-cgi/l/email-protection_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 毫秒的时间。在代码中,它来自这个块(实际上直接来自“HTTP Server 2”)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- 服务器.cpp 和连接.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
)
);
从 start() 到:
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()时,已经过去了700ms。
有人有什么想法吗?我完全迷路了。
非常感谢!