Ab – Apache Bench hanging with -k Keep-Alive switch
November 25th, 2009This problem was making me go blind! I’m testing Spinneret with ab at the moment, trying to make sure there’s no disastrous behaviour under load. I found that ab just stopped after the first request if I used the -k switch. I’m not sure the problem is my fault, exactly, but I have ‘solved’ it. HTTP 1.0 didn’t have persistent connections. In HTTP 1.1, the default behaviour is persistence, so only a mechanism for explicitly closing a connection is provided.
Apache bench offers the ‘-k’ switch to allow you to test your webserver with persistent connections, but sends a HTTP/1.0 request. The -k switch causes ab to send the header “Connection: Keep-Alive” to the server. Spinneret’s debugging log confirmed a response was sent back, and the ‘-v’ switch (verbose) in ab would even show that it received the response, but it would just ‘hang’ at that point, until it timed out:
LOG: Response code = 200
apr_poll: The timeout specified has expired (70007)
I wasted a lot of time imagining what could be wrong with it before I decided to just duplicate the response from an Apache server that worked with the -k switch in ab. I spotted that Apache was returning the ‘Connection: Keep-Alive’ header. Adding that header field to a Spinneret response to a HTTP/1.0 request that contains it solves the problem with ab.
This behaviour isn’t specified anywhere, but it is suggested in an Internet Draft for HTTP/1.1 at w3.org:
The
Connection
header field with a keep-alive keyword must be sent on all requests and responses that wish to continue the persistence.
Perhaps the nice people at Apache might consider some less baffling behaviour for when amateur webserver programmers attempt to pick up their tools!