Trying to understand how keep-alive works

Today we encountered a problem on the server, when files/scripts took more that 3 seconds to load. The solution was simple - just increasing MaxClients to the estimated memory limit. But I am worried about scalability of that solution and it doesn't seems too reliable — should load increase slightly problem will occur again.

The nature of the webservice we are developing — small online game — requires us to embed AJAX mechanism which sends a beacon each 15 seconds indicating that client is online.

Let us imagine following setup. Apache 2 (mpm_prefork), MaxClients = 150, KeepAlive = on, KeepAliveTimeout = 5. There are 300 users online. Do I understand it correct — if all 300 users will send a beacon simultaneously (just by retrieving beacon.php script using POST) — first 150 clients will get an answer almost momentarily while other 150 will have to wait for 5 seconds before they get an answer?

And second question. What is the best solution in my case? Disabling keep alive at all?


MaxClients in apache 2 is the maximum number of simultaneous requests that will be served across all apache processes. With the prefork mpm, that is also the maximum number of apache processes that will run concurently and the maximum number of open incoming network connections to your web server.

The whole point of KeepAlive is to reduce the overhead of initiating new TCP connections for every HTTP request when accessing a site, as each new page can potentially require tens of documents (initial html, css, javascript, images, etc). The end result is pages that load faster.

MaxKeepAliveTimeout indicates how long the web serve will wait for an additional hHT request from an idle client before closing the connection, enabling it to service new incomng connections.

In your case, if you have 150 clients sending the beacon at once with KeepAlive enabled, then yes it will take 5 more seconds before other users can beacon in. Assuming a requirement of sending a beacon every 15 seconds that's 450 max concurent users.

Solutions:

  • you could reduce the MaxKeepAliveTimeout to 2 seconds, there's diminishing returns when it is increased. The maximum benefit is for initial page loads, and there's virtually no delay between those requests.

  • you could disable KeepAlive altogether, increasing the load time of all your pages, assuming that most users spend most time in-game.

  • keepalive has to be enabled client side as well as server side to be used. Assumng you control your client side javascript, it is possible to disable keepalive on the client side for a specific request, using:

    connection.setRequestProperty("Connection", "close");
    
  • Similarly, you could disable Keepalive for specific http requests on the server side by manipulating the Connection response header.

Hope this helps!


The whole concept of how Apache2 keep-alive mechanism works is very well described in this article Tuning Apache

You need to find some balance between MaxClients and KeepAliveTimeout values to use this feature. Either increase the first one according the available memory in the server or decrease the second one.