Sockets are the basis of most application layer protocols. Common sockets fall into two types: TCP and UDP. HTTP uses TCP sockets with port 80 by default. Why is that? Because TCP connections are reliable, other protocols are allowed [1]. However, it is the TCP connection that is used in the beginning that makes the following optimization possible.

1. The initial HTTP connection

A server needs to serve many requests. If these requests are continuously opened after the connection, there will be a large number of connections in the waiting state to be maintained, and the number of processes, memory resources, bandwidth resources and file descriptors has an upper limit. Due to the intermittent characteristics of data exchange between the client and the server, therefore, Originally – HTTP1.0 – the protocol was designed to establish connections at request time and release connections at request time, freeing resources to serve other clients as quickly as possible. [2]

As a result, early HTTP server implementations created a new TCP connection for each HTTP request/response, broke the response, and created another connection for the next request. This was a reasonable solution at the time: simple and crude, no managed connections, and better performance.

Developing rapidly, but next, HTTP web page with more images, forms, a single user in a short period of time needs to be repeated requests on the server resources, without connection already cannot satisfy the increasing demand, even sacrifice some server resources to maintain the TCP connection, than every requests a resource to establish the cost of a new request, This cost includes network bandwidth, time, creating, closing connections…

2. A TCP connection completes multiple HTTP requests and responses

Header: keep-alive: timeout=5, Max =100 In HTTP1.1, simply set the default state to on, unless you explicitly declare Connection: Close.

This is often referred to as Persistent Connections. It is suitable for scenarios where the client and server need to frequently transfer data.

Long connections can be used in many ways once they are enabled, such as HTTP Pipelining.

HTTP Pipelining technology

Browser after parsing HTML, found that there are three images need to download, this time how to use this can be two-way communication at any time long connection to complete the three resources to obtain it? Method 1: initiate the first image request, and wait for the server to return the result, then initiate the second image request… Until all are gained. Method 2: make the first image request, and then parse, find that the second image is needed, then send the second image request (regardless of whether the first request returned or not), and wait for the server to return the result, and the server guarantees: three responses in the same order as my three requests.

[3]

  1. As FIFO is used, it is easy to cause Head of line blocking, that is, even if the second, third and fourth requests are ready, if the first request is not completed, it should wait until the first request is ready to send, so the actual optimization effect is not obvious
  2. The big reason: if the server is turned on, it runs the risk of a DDos — a big, cobbled together request that the server can’t handle
  3. Can only be idempotent HTTP methods — probably because of the need for retries, if THE POST is retried multiple times, causing duplicate commits
  4. There’s proxy server instability and so on but there are still people working on it and some solutions, but it’s still not popular

4. Pipelining

A TCP connection can be reused many times, but Pipelining cannot be reused in environments that require parallel loading due to the limitations and limitations of Pipelining.

Clients that use persistent connections SHOULD limit the number of simultaneous connections that they maintain to a given server. A single-user client SHOULD NOT maintain more than 2 connections with any server or proxy. It’s just SHOULD NOT, you didn’t say MUST NOT, so I’ll try to create a few more, we’ve gone through several versions of the adjustment, we think that for the same field, the value of 4-6 concurrent connections is more reasonable.

Of course, this default value can also be modified by the user

5. How to obtain the latest information on the server in real time?

5.1 the polling (polling)

The problem with polling: without data updates, the request is meaningless. The key is the timing of polling — the number of users, real-time row requirements, and server performance are all taken into account

5.2 a comet

The client initiates a connection and returns the result when there is an update. After the client returns the result, it immediately establishes a new connection and waits for the new data to return. What a clever plan!

5.3 HTTP chunked technology[4]

When the server has some content ready, it outputs some content, and when the browser receives some content, it responds to some content.

  1. Java, PHP: Flush () Node FlushHeaders (); if no end is executed, write is output without flush. If no end is output, force a call to response.flushheaders (). In general, frameworks offer better encapsulation without an excuse for relatively low-level operations, such as Express’s Render, which outputs everything at once, so there seems to be no way to export parts in Express — I haven’t looked at the source code yet
  2. XHR support – Firefox and Safari support is better, it is supported directly, Chrome needs to set a header:X-Content-Type-Options: nosniff.It was in this problem that I found the solutionCurl does not print the output immediately if you do not end it with a line break.
  3. Note: If there are load balancing devices such as Nginx, need to be in theseTurn caching logic off in service configurationOr declare an unexpected cache in the HeaderX-Accel-Buffering: no. If there is a problem, it may be that TCP is not enabled somewhere in the middleTCP_NODELAYParameters. Wireshare listens for segmented requests:

In the following example, three chunks of length 4, 5 and 14 are shown. The chunk size is transferred as a hexadecimal number followed by rn as a line separator, followed by a chunk of data of the given size.

  4\r\n
  Wiki\r\n
  5\r\n
  pedia\r\n
  E\r\n
  in\r\n \r\n chunks.\r\n 0\r\n \r\nin
  chunks.
Copy the code

Extension: Nagle algorithm enabled by TCP default

On a single TCP link, when multiple short fragments need to be transmitted in a short period of time, the transmission mode is as follows:

The TCP connection for the Nagle algorithm is closed

TCP connection of Nagle algorithm is enabled

www.potaroo.net/ispcol/2004…

What is more interesting is that when Nagle algorithm and delay ACK two optimization conditions meet, it will cause obvious delay

Question to consider: How is Bigpipe implemented?

Basically, this is a practical application of segmenting HTML files. Can you use a similar technique to send JSON? Of course there is: eBay also has a JsonPipe solution that solves the problem of sending json that cannot be directly parsed if it is a standard JSON. {” id “: 12345,” title “:” Bruce Wayne “, “price” : “$199.99″} \ n \ n {” id “: 67890,” title “:” Bane “, “price” : “$299.99”}

Distinction: chunked is not the same as 206 requests

If you look at the request in DevTools, you’ll see that the status code of the MP3 file is 206 most of the time. How is this different from a segmented transfer? In case of 206, the client and server ask for some data, for example, the first 3MB of an MP3 and then wait for the user to play the music. At some point in time, I load that part of the data again. When the user hits 75% of the progress, I request a small piece of data from 75% of the requested location. In this way, the split – end download is achieved. The application scenario is file download and online playing of music or video files. Thunderbolt and other multi-threaded download tool application is the main feature – at the same time from a different location of the file request, all completed, and then put together a complete file. Chunked is a live stream output, while 206 is what you watch on demand.

SSE 5.4

Server-sent Events is technically nothing new, but a step forward in terms of standardization and API design.

  1. Text /event-stream, charset=utf8
  2. The browser receives a one-way message from the server
  3. It is important to note that this is not an innovation at the transport level, but a new protocol at the application level, so it is not in the RFC specification document, but the W3C specification. It’s described in detail here

5.5 introduction of WebSocket

Over HTTP, through the upgrade, complete the two-way connection – using the same TCP channel established before, complete by handshake, direct over TCP communication. Tools.ietf.org/html/rfc645… Capable of transmitting binary streams in both directions. There are a lot more things you can do, you can develop your own protocols on top of that, you can also port other protocols to this link. The most common library is socket.io

5.6 HTTP2.0

The main features

  1. New binary transfer
  2. Messages are multiplexed over shared links, sent randomly and received randomly. How do I determine? Let’s do it by ID.
  3. Header compression: Headers that have already been sent are not sent in subsequent messages
  4. You can cancel a request
  5. ServerPush
  6. The browser supports HTTPS only

New changes

The multiplexing and ServerPush aspects of HTTP2.0 make some of the original performance tuning principles for HTTP itself less important:

  1. The request does not need to be merged
  2. No more multi-domain deployment
  3. In addition, HTTP2.0 is not suitable for all scenarios, such as large file downloads.

Consider: with HTTP2.0, is chunked, SSE, WebSocket unnecessary?

Chunked is part of the HTTP1.1 protocol itself and is an application-layer data transfer method. SSE is a new convention based on chunked technology. WebSocket can be understood as a new form of Socket, which can do things similar to the basic functions of traditional sockets. And HTTP2.0, which is an improvement on the way HTTP1.1 is reused, is a server and browser thing, and does not provide any new JS interface to the front end to operate this link and be aware of ServerPush etc. Another problem is that with the update to HTTP2.0, the old WebSocket operations (handshake, communication, all based on HTTP1.1) are no longer available. WebSocket based on the HTTP2.0 standard is still in its infancy. WebSocket over HTTP/2WebSocket2 over HTTP/2

The resources


  1. (www.w3.org/Protocols/r)… ↩ ︎

  2. Blog.csdn.net/bingjing123… ↩ ︎

  3. Stackoverflow.com/questions/3… ↩ ︎

  4. En.wikipedia.org/wiki/Chunke… ↩ ︎