Keep-alive (persistent) connections with Java Servlets
If you are using a Servlet to serve frequently-accessed content, then you may
need to concern yourself with the issue of keep-alive connections
(also called persistent connections). In the very early days of HTTP,
it was common for every single request to involve opening and closing a new connection.
For example, to display a page with 9 images, this would involve a sequence of 10 separate
connections to the server. Since HTTP 1.1, the default behaviour has been for connections
to be kept open or "alive" between requests.
In order for a single connection to serve multiple requests, a little bit of trickery
is necessary within the HTTP protocol, because we can't just mark the end of the data by closing
the connection. The most common solution is that before every
response (i.e. page, image etc) returned, a Content-Length header is inserted
which gives the length in bytes of the following data. This is easy for the web server if it's
serving a static page such as an HTML file. But it's more difficult with dynamic
content generated, for example, by a PHP script or Java Servlet. From the
perspective of a Java Servlet, there are essentially two solutions.
The first solution is to rely on buffering by the web server itself.
In other words, we return output from our Servlet as normal, and hope that the server (Apache, IIS etc) will
automatically be buffering our output in order to count its length and insert a Content-Length header1.
Some web servers do appear to do this.
If you can determine that your web server is indeed buffering, then life is a bit easier.
Below, we'll see a simple way to determine if the web server is buffering your Servlet output.
The second solution is to manually set a Content-Length header within the Servlet itself.
To do this, we need to be able to predict the length of the output we're going to send. Or in the worst case,
buffer it ourselves in order to measure the length before sending it.
Does my web server buffer Servlet output?
A simple way to determine if your web server is buffering the output of your Servlet is to
see what it's outputting! If you're feeling fancy, you could do this with a packet sniffer.
But a simpler way is to use a humble telnet connection. The procedure is as
- open a command window/terminal and make sure it's got a fairly large buffer size
so that you won't loose the output you're looking for (see here for instructions on
setting the buffer size of a Windows command window);
- telnet to port 80 of your host:
- manually type a couple of lines of HTTP header:
GET /MyServletPage.html HTTP/1.1
- press enter a couple of times (the end of the header section is marked by a blank line in HTTP);
- if you've typed everything correctly, you should get your Servlet output spewed back at you,
prefixed with the HTTP headers— this is where you may need to scroll up to
see them— which should look something like this:
HTTP/1.1 200 OK
Date: Tue, 28 Oct 2008 16:37:55 GMT
Server: Scratchy/2.0.56 (PinkOS)
Content-Type: text/html; charset=UTF-8
- the magic header you're looking for is Content-Length as above: if this is
present, then your web server is buffering your servlet content, and your Servlets will
be compatible with keep-alive connections.
If the Content-Length header isn't present, then you probably want to
set the Content-Length header within your Servlet.
1. HTTP provides another solution called "chunked encoding", in which the length of the whole
content isn't supplied at once, but rather of individual "chunks" or "buffers", and eventually the
final one is signalled. As far as I am aware, few servers actually support sending the output from
a Servlet as chunked encoding.