이상한 문제가 있습니다. 나는 C++ Boost.ASIO 웹 서버를 가지고 있고,이 코드를 사용하고 들어오는 요청을 처리하기 위해 :C++ Boost.ASIO async_read_until slow
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_는"내 부스트 :: ASIO :: IP : TCP : 소켓입니다 및 "response_"은 boost :: asio :: streambuf입니다.
나는 요청의 헤더를 잡으려고하고 있습니다. 그리고 나서 나중에 transfer_exactly가 구문 분석 된 "Content-Length"와 일치하는 두 번째 async_read_until을 수행합니다. 요청 헤더. 문제는 위의 코드가 매우 현대적인 서버 (handle_read_headers()가 호출 될 때까지 읽기 블록에서 반환)에 100-900ms가 걸리는 것입니다.
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를 트리거 수행합니다 들어오는 요청과 같은 전체 페이지 읽기) - 실제로는 정규식을 걸고있다. 그리고 이러한 요청은 Google에서 나오므로 자신의 목적이 지연되지 않는다고 확신합니다.
돌아 오는 데 너무 오래 걸리는 이유를 간과 할 수있는 것이 있습니까? aync_read_until을 가진 다른 catch는 내가 놓친 것일 수 있습니까?
감사합니다.
편집/업데이트 : 좋아, 이제 나는 매우 혼란스러워. 메가 바이트의 제안을 시도하면서, 나는 streambuf에서 문자 배열로 전환했다. 그런 다음 async_read_until 대신 async_read_some을 사용하도록 코드를 리팩토링하고, 수동으로 구분 된 문자를 스캔했다. 또한 OS 변수 (sysctrl.conf)를 모든 기본 변수로 재설정하여 가능성을 줄였습니다. response_ 지금
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
)
);
입니다 : 불행하게도, 난 여전히 같은 들어오는 POST 요청과) (handle_read를 호출 다음 코드 100-900ms 지연을보고 있어요 아무 소용이
boost::array<char, 4096> response_;
(동일 100-900ms 지연). 이것이 정상적인 방법은 없습니다 - 어떤 생각입니까?
EDIT2 : Rhashimoto의 추천 당 , 나는 핸들러 추적을 활성화하고 로그에서이 기이을 발견하십시오 async_accept와 async_receive 사이에 700 밀리가 있습니다
[2013-07-05 15:58:39 - Thread 7fae57e3f700]: Incoming connection (0ms elapsed)
@asio|1373054319.874916|506*508|[email protected]_receive
@asio|1373054319.874963|506*509|[email protected]_accept
@asio|1373054319.875008|<506|
@asio|1373054320.609088|>508|ec=system:0,bytes_transferred=512
@asio|1373054320.609233|508*510|[email protected]_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
. 코드에서는 (http://www.boost.org/doc/libs/1_54_0/doc/html/boost_asio/examples/cpp03_examples.html의 "HTTP 서버 2"에서 거의 직선 - server.cpp 및 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
)
);
하고 처음부터() :
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가 경과했습니다.
아무도 아이디어가 있습니까? 나는 완전히 잃어 버렸다.
감사합니다.
실제로이 문제가 내 소켓 객체가 어떻게 든 사용 중이거나 과부하 상태가 될 수 있는지 궁금합니다. 그것은 OS 내에서가 아니므로 아마 내 프로그램의 다른 부분의 한가운데에있을 것입니다 .... 가능합니까? 그리고 async_read_until에서 지연이 발생할 수 있습니까? – Harry
그리고 Keep-Alive 연결을 많이 사용하고 있습니다. 각 요청 후에 소켓 종료를 호출하면 안됩니까? – Harry
우선, 성능 프로파일 러를 사용합니까? 그것은 무엇을 말하는가? –