Saturday, May 9, 2009

HTTP Persistent Connection

HTTP/1.1 offers HTTP persistent connection. This persistent connection provides a huge improvement in HTTP performance. HTTP persistent connection allows the same TCP connection to send/receive data over the same TCP socket without opening a new socket.

If you have notice, in HTTP/1.0, it does not provide HTTP persistent connection. As a result, each HTTP call opens a new connection.

So, what the issue?

The issue is TCP termination. Whenever a TCP connection terminate, the TCP socket will goes into a Time-Wait state. TCP Time-Wait state make the device to wait for a period of time equal to double the maximum segment life (MSL) time. This gives enough time to ensure the ACK it sent to the client was received. And, the damaging effect is Port Availability, that is, you cannot use that port for 2*MSL time.

In Window and Linux environment, the default TCP Time-Wait is 2 minutes. This means: After a TCP connection is closed, the port is not available for the next 4 minutes.

You may ask, what is the big deal? Imagine... If you are doing HTTP image streaming and each HTTP image fetch open a new connection. Lets do some calculation. If you are streaming at 30FPS for a camera, you will need 1800 ports per minutes. As TCP Time-Wait for Window is 4 minutes, it will use almost 7200 ports in 4 minutes. Very soon, you will use up all the available ports in the system.

In the HTTP/1.0 world, the only solution may be reducing TCP Time-Wait and increase the maximum number of ports can be use in the system.

In Window, you can set

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\TcpTimedWaitDelay

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\MaxUserPorts

to tune the system. See TCP TIME-WAIT Delay for further details.

HTTP/1.1 TCP connection reuse helps to solve this issue. It adds a HTTP header Connection: Keep-Alive to denote TCP connection resuse. In Java Socket, HTTP persistent connection is implemented. It has a default TCP keep-alive and a maximum persistent connection of 5. See Java HTTP Persistent Connection

But, please be aware of 1 thing. That is Connection: close. HTTP/1.1 defines as follows

HTTP/1.1 defines the "close" connection option for the sender to signal that the connection will be closed after completion of the response. For example, Connection: close
in either the request or the response header fields indicates that the connection SHOULD NOT be considered `persistent' (section 8.1) after the current request/response is complete.

That mean, if a HTTP/1.1 reply contains a Connection: close header, the socket will be closed and cannot be reuse. This is true for Java. Please beware.

One way to check if you are using HTTP persistent connection correctly is the command netstat -a in Window. You SHOULD NOT see a lot of TCP connection in TIME-WAIT state under the same Foreign Address. You SHOULD NOT see TCP connection increasing like a bull too.

If you see such events happening, you should start looking at network packet level to diagnose the issue. You may have a Connection: close somewhere. Wireshark is one of the good tools for this.

No comments:

Post a Comment