Long HTTP connection

HTTP: 1.0 HTTP: 1.1 HTTP: 1.0 HTTP: 1.1 HTTP: 1.0 HTTP: 1.1 HTTP: 1.0 HTTP: 1.1

Keep-alive long connection:

We all know that HTTP protocol is based on TCP/IP protocol, so in order to reduce the unnecessary overhead caused by three handshakes and four waves, we should reuse the current TCP connection as much as possible to reduce the overhead caused by TCP connection establishment and closure. The HTTP protocol has a keep-alive field in the request header to establish a long connection in version 1.0. The biggest difference is that 1.0 requires the server to actively inform the server of the need to establish a long connection, while version 1.1 supports long connections by default.

Here is a brief introduction to the function and working mechanism of the long connection to understand the following content:

As shown in the figure above, each time a client sends a request without the long connection function, it goes through this process:

  1. The TCP connection is established after three handshakes.
  2. After the establishment, the client sends a request to the server.
  3. After receiving the request, the server responds to the request.
  4. Disconnects the TCP connection with four waves.

If our client has multiple requests, we need to establish multiple TCP connections, so if we send a hundred requests, that is not going to experience a hundred TCP connections and disconnections. There is no doubt that the cost of doing so is huge, so I have to think about how to solve this problem.

In fact, keep-alive is designed to solve this problem. When the client and server establish a TCP connection, keep-alive can reuse the current TCP connection.

Http1.1 request link process, as shown below:

Team head block

When we looked at the picture above, did we see anything wrong?

Let’s start by dividing the above request into three HTTP requests. I’ll number the above requests:

When we request to send 1 got the normal response, after we send 2 requests to the server, because the network bandwidth, or a variety of reasons, lead to send the request to the server is slow or server for the slow response will form a wait state, since the client requests sent to the server in the form of a queue. Therefore, no response is received after request No. 2 is sent. Therefore, request No. 3 can be sent only after request No. 2 is completed.

This is known as queue head blocking.

Here’s how Wikipedia explains it:

In the context of computer networks, head-of-line blocking is a performance limitation. The reason is that the first packet in a column (queue head) is blocked and the whole column is blocked. For example, it can occur in a switch with cached input, it can occur because of out-of-order transfers, or it can occur when there are multiple requests in the HTTP pipeline.

In fact, it is not difficult to find that although the TCP connection is multiplexed, but the request is still one by one requests, arbitrary can easily cause blocking problems.

So how do we solve this problem?

To improve speed and efficiency, HTTP1.1 goes further by supporting the use of pipelining features over persistent connections. Pipelining allows the client to send the next request before the sent request receives the response from the server, thereby reducing the wait time and improving throughput. If multiple requests can be sent in the same TCP section, network utilization can be improved, as shown in the figure below:

As you can see from the figure, three clients can make concurrent requests without waiting for a response from the previous request before sending the next one.

The problem of blocking the next request because the last request did not respond is not completely solved, because this approach only solves the problem on the client side, not the server side. The server still returns in FIFO form, meaning that if the response to request 1 is blocked, request 2 will wait for request 1 to finish processing and return before responding to the client.

Here inevitably some small partners will have doubts, why should the server deal with it?

There are some limitations to using HTTP pipelining:

1. Pipelining requires the server to return the response (FIFO) in the order in which the request was sent. The reason for this is simple: HTTP requests and responses are not numbered and cannot be associated with out-of-order responses.

2. When the client supports pipelining, it needs to hold unreceived requests and resend these requests when the connection is unexpectedly interrupted. If the request is just to get data from the server, there is no impact on the resource, whereas if it is a request to submit information, such as a POST request, it may cause multiple commits to change the resource, which is not allowed. Requests that do not affect server resources have a technical term called idempotent requests. The client must make idempotent requests when using pipelining.

Pipelining and pipelining are not supported. Let’s compare them together:

How to solve

Since pipelining itself can cause queue blocking problems, modern browsers turn it off by default.

The HTTP protocol recommends that you use TCP connections concurrently, and this refers to TCP concurrent connections. RFC2616 clearly limits each client can establish two long connections, here emphasize that the number of long connections established by the client is initiated for domain names, for example, when we visit the a.com website, the client and the a.com server to establish long links is 2.

But generally the browser will increase the number of concurrent link to six to eight, Google browser is six, namely page if there are multiple HTTP requests for the same domain, Google browser will build six long TCP connection for this domain name, in each long connection to handle HTTP requests, but this approach is a challenge to the server is very large, Some Web optimizations break the 6 to 8 limit, which is domain slicing. Because long connections are for the same domain, the number of long connections can be broken if developers distribute resources across different domains.

Suppose there are 100 images on the page. Based on this example, let’s use the diagram to represent the change from HTTP1.0 to HTTP1.1 as three diagrams:

Http1.0 era: 100 HTTP requests to establish 100 TCP connections.

In the http1.1 era, TCP supported long connections and each TCP could handle multiple HTTP requests.

conclusion

Here’s a summary:

In the first part, we introduced what HTTP long connections are, mainly using TCP long connections to reduce the overhead of establishing and disconnecting TCP connections.

In the second part, we introduced what is called queue head blocking, which is caused by the failure of subsequent requests in the queue to be processed.

In part 3, we looked at how to solve this problem, for example with concurrent TCP connections. Since the client limits the number of TCP connections, you can slice up the domain name to overcome this limitation.

Above is my team head block some superficial understanding, if there is no expression to go, welcome to comment area pointed out, I will correct in time.