Я в настоящее время пытаюсь создать http-сервер с помощью Boost.Asio, я сделал это следующим образом: HTTP Server 3.Boost :: Asio HTTP Server чрезвычайно медленный
В настоящее время я просто прочитал запрос и всегда возвращаю сообщение OK. Так что ничего особенного или много времени.
Проблема, с которой я сталкиваюсь, работает на сервере с 12 потоками (16 ядер на 2,53 ГГц), сервер обрабатывает 200-300 запросов в секунду.
Я сделал то же самое в C#, используя HttpListener, работающий с 12 потоками, обрабатывает запросы около 5000-7000 arround.
Какая черта Boost.Asio делает?
Использование инструментария профилирование с Visual Studio получить следующие "функции с большинством индивидуальная работа":
Name Exclusive Time %
GetQueuedCompletionStatus 44,46
std::_Lockit::_Lockit 14,54
std::_Container_base12::_Orphan_all 3,46
std::_Iterator_base12::~_Iterator_base12 2,06
Edit 1:
if (!err) { //Add data to client request if(client_request_.empty()) client_request_ = std::string(client_buffer_.data(), bytes_transferred); else client_request_ += std::string(client_buffer_.data(), bytes_transferred); //Check if headers complete client_headerEnd_ = client_request_.find("\r\n\r\n"); if(client_headerEnd_ == std::string::npos) { //Headers not yet complete, read again client_socket_.async_read_some(boost::asio::buffer(client_buffer_), boost::bind(&session::handle_client_read_headers, shared_from_this(), boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred)); } else { //Search Cookie std::string::size_type loc=client_request_.find("Cookie"); if(loc != std::string::npos) { //Found Cookie std::string::size_type locend=client_request_.find_first_of("\r\n", loc); if(locend != std::string::npos) { std::string lCookie = client_request_.substr(loc, (locend-loc)); loc = lCookie.find(": "); if(loc != std::string::npos) { std::string sCookies = lCookie.substr(loc+2); std::vector<std::string> vCookies; boost::split(vCookies, sCookies, boost::is_any_of(";")); for (std::size_t i = 0; i < vCookies.size(); ++i) { std::vector<std::string> vCookie; boost::split(vCookie, vCookies[i], boost::is_any_of("=")); if(vCookie[0].compare("sessionid") == 0) { if(vCookie.size() > 1) { client_sessionid_ = vCookie[1]; break; } } } } } } //Search Content-Length loc=client_request_.find("Content-Length"); if(loc == std::string::npos) { //No Content-Length, no Content? -> stop further reading send_bad_request(); return; } else { //Parse Content-Length, for further body reading std::string::size_type locend=client_request_.find_first_of("\r\n", loc); if(locend == std::string::npos) { //Couldn't find header end, can't parse Content-Length -> stop further reading send_bad_request(); return; } std::string lHeader = client_request_.substr(loc, (locend-loc)); loc = lHeader.find(": "); if(loc == std::string::npos) { //Couldn't find colon, can't parse Content-Length -> stop further reading send_bad_request(); return; } //Save Content-Length client_request_content_length_ = boost::lexical_cast<std::string::size_type>(lHeader.substr(loc+2)); //Check if already read complete body if((client_request_.size()-(client_headerEnd_)) < client_request_content_length_) { //Content-Length greater than current body, start reading. client_socket_.async_read_some(boost::asio::buffer(client_buffer_), boost::bind(&session::handle_client_read_body, shared_from_this(), boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred)); } else { //Body is complete, start handling handle_request(); } } } }
Edit 2:
Клиент, используемый для тестирования, представляет собой простую C# -Application, которая запускает 128-Threads каждый раз итерации 1000 раз без сна.
System.Net.HttpWebRequest req = (System.Net.HttpWebRequest)System.Net.WebRequest.Create(BaseUrl);
req.Method = "POST";
byte[] buffer = Encoding.ASCII.GetBytes("{\"method\":\"User.Login\",\"params\":[]}");
req.GetRequestStream().Write(buffer, 0, buffer.Length);
req.GetRequestStream().Close();
Внесите код просто. Это не оптимально. request_parser в примере синтаксического анализа на каждый байт и push_back на строку, без каких-либо резервов. Существует также недокументированная проблема с asio :: strand. – ForEveR
Трудно сказать, не видя какой-то настоящий код. Пробовали ли вы его профилировать? Кроме того, вы скомпилировали его с любыми оптимизациями? – Nim
Это часто проблема с выходом Nagle. См: http://stackoverflow.com/questions/2039224/poor-boost-asio-performance/2039378#2039378 – janm