2016-12-08

Brief

HTTP works with request-response: client connects to server, performs a request and gets a response. Normally, the connection to an HTTP server is closed after each response. With HTTP keep-alive you keep the underlying TCP connection open until “certain criteria” are met.

“Connection:keep-alive” is a method to allow the same tcp connection for HTTP conversation instead of opening a new one with each new request.

More simply put, it is a communication between the web server and the web browser that says “you can grab more than just one file at a time“. Interaction diagram as follows:

tcp_keepalive

That enable HTTP ‘keep-alive’ is callded ‘HTTP persistent connection‘. See HTTP persistent connection for some advantages , such as:

  • Lower CPU and memory usage : by opening and closing fewer TCP connections, CPU time is saved in routers and hosts (clients, servers, proxies, gateways, tunnels, or caches), and memory used for TCB (TCP control blocks) can be saved in hosts.
  • Reduced latency : latency on subsequent requests is reduced since there is no time spent in TCP’s connection opening handshake.
  • HTTP pipelining : HTTP requests and responses can be pipelined on a connection. Pipelining allows a client to make multiple requests without waiting for each response, allowing a single TCP connection to be used much more efficiently, with much lower elapsed time.

How enable ‘keep-alive’?

apache

Open up apache’s configuration file and look for the following settings. this file is called httpd.conf. The following settings are noteworthy :

#
# KeepAlive: Whether or not to allow persistent connections (more than
# one request per connection). Set to "Off" to deactivate.
#
KeepAlive On

#
# MaxKeepAliveRequests: The maximum number of requests to allow
# during a persistent connection. Set to 0 to allow an unlimited amount.
# We recommend you leave this number high, for maximum performance.
#
MaxKeepAliveRequests 100

#
# KeepAliveTimeout: Number of seconds to wait for the next request from the
# same client on the same connection.
#
KeepAliveTimeout 100

nginx

keep-alive is enabled by default on nginx, however, in some cases, it can be disabled. You can enable it using HttpCoreModule. Look for the value keepalive_disable, which is in a lot of cases the reason why keep-alive is not working. Before enabling it, make sure to know the reason why it’s disabled in the first place before attempting any changes.

As above, describes the advantages and ways of “keep-alive” mode. Here, take “Establish a TCP connection“ as example, analysis necessity of enabling keep-alive mode.

Why enable ‘keep-alive’?

TCP连接并非真真地手牵手,而是双方共同维持的一组状态。因此,单单的一次握手,无法确保双方建立连接,需要经过“三次握手”,最终确认双方达成“建交”共识。一个TCP连接建立过程,如下图:

establish_tcp

一个已建立的TCP连接由一对socket组成。socket以“FD(file descriptor)”的形式存放在客户端和服务端的内存中。针对不同的TCP连接,通过定义“四元组”进行唯一区别。“四元组”的结构如下:

{
  "dest_IP": "目标地址",
  "dest_port": "目标地址端口",
  "src_IP": "源地址",
  "src_port": "源地址端口"
}
本地curl一下百度,对照客户端和服务端socket的四元组结构,如下:
client_socket:{
  "dest_IP": "115.239.217.68",(百度IP)
  "dest_port": "80",(端口)
  "src_IP": "192.168.10.226",(本地IP)
  "src_port": "58565" (临时分配的端口)
}

server_socket:{
  "dest_IP": "192.168.10.226",
  "dest_port": "58565",
  "src_IP": "115.239.217.68",
  "src_port": "80"
}

一次TCP连接的建立会占用CPU、内存等资源,频繁地创建TCP连接将给CPU、内存带来压力。其次,TCP建立前的“三次握手(three-way handshake)”和“ 慢启动(slow start)”会拖慢数据包传输进度。下文摘抄自《High Performance Browser Networking》一书中关于这两个因素的解读:

To illustrate the impact of the three-way handshake and the slow-start phase on a simple HTTP transfer, let’s assume that our client in New York requests a 64 KB file from the server in London over a new TCP connection , and the following connection parameters are in place:

  • Roundtrip time: 56 ms
  • Client and server bandwidth: 5 Mbps
  • Client and server receive window: 65,535 bytes
  • Initial congestion window: 10 segments ()
  • Server processing time to generate response: 40 ms
  • No packet loss, ACK per packet, GET request fits into single segment

tcp_threeway

264 ms to transfer a 64 KB file on a new TCP connection with 56 ms roundtrip time between the client and server! By comparison, let’s now assume that the client is able to reuse the same TCP connection (Figure 2-6) and issues the same request once more.

tcp_threeway

The same request made on the same connection, but without the cost of the three-way handshake and the penalty of the slow-start phase, now took 96 milliseconds, which translates into a 275% improvement in performance!

Congestion window size growth:

tcp_threeway

① “三次握手”:确认双方达成一致‘连接’共识,是数据传送的前提。
② “慢启动”:通过“每次double上一次发送数据包”的试探方式,找到下行的带宽大小。避免发送端发送的数据包太大,接收端无力承受,导致数据丢失的情况发生。
这两个阶段,是一个新建立的TCP连接,必须经历的阶段。

Questions

  • browser:同时支持最多长连接数?
  • apache:同时支持最多长连接数?
  • nginx:同时支持最多长连接数?




Appendix




(本文章非原创 由本人摘录整理)