Search code examples
c++boost-asio

Server hangs for while after 16000 requests


I am new to boost::asio. Trying to run

ab -n 20000 -c 5  -r http://127.0.0.1:9999/

Test gets stuck after 16000 request every time. But it does complete. Also I get lots of failed request.

What code is doing :

  • A. Create Service
  • B. Create Acceptor
  • C. Bind and listen
  • D. Create Socket
  • F. Do async_connect
  • G. In async_connect handler close socket. Create New One And do async_connect with same handler.

Code follows :

#include <iostream>
#include <functional>
#include <string>
#include <boost/asio.hpp>
#include <boost/bind.hpp>
#include <boost/thread.hpp>
#include <memory>

// global variable for service and acceptor
boost::asio::io_service ioService;
boost::asio::ip::tcp::acceptor accp(ioService);

// callback for accept
void onAccept(const boost::system::error_code &ec, shared_ptr<boost::asio::ip::tcp::socket> soc) {
    using boost::asio::ip::tcp;
    soc->send(boost::asio::buffer("In Accept"));
    soc->shutdown(boost::asio::ip::tcp::socket::shutdown_send);
    soc.reset(new tcp::socket(ioService));
    accp.async_accept(*soc, [=](const boost::system::error_code &ec) {
            onAccept(ec, soc);
        });
}

int main(int argc, char *argv[]) {
    using boost::asio::ip::tcp;
    boost::asio::ip::tcp::resolver resolver(ioService);
    try {
        boost::asio::ip::tcp::resolver::query query("127.0.0.1", boost::lexical_cast<std::string>(9999));
        boost::asio::ip::tcp::endpoint endpoint = *resolver.resolve(query);
        accp.open(endpoint.protocol());
        accp.set_option(boost::asio::ip::tcp::acceptor::reuse_address(true));
        accp.bind(endpoint);
        cout << "Ready to accept @ 9999" << endl;

        auto t1 = boost::thread([&]() { ioService.run(); });

        accp.listen(boost::asio::socket_base::max_connections);
        std::shared_ptr<tcp::socket> soc = make_shared<tcp::socket>(ioService);

        accp.async_accept(*soc, [=](const boost::system::error_code &ec) { onAccept(ec, soc); });

        t1.join();
    } catch (std::exception &ex) {
        std::cout << "[" << boost::this_thread::get_id() << "] Exception: " << ex.what() << std::endl;
    }
}

For completeness:

  1. I changed my code as per @Arunmu
  2. I used docker with linux because of socket problem suggested by @david-schwartz
  3. Server never hangs now.
    • Single Thread - 6045 req per sec
    • Threads - 5849 req per sec
  4. Using async_write

Solution

  • You're running out of local sockets. You should not be testing by generating all your load from a single IP address. (Also, your load generator should be smart enough to detect and work around this condition, but alas many aren't.)