http/2.0 "multiplexing" realization principle // reproduced

1. Optimized highlights of HTTP/2 over HTTP/1.1

HTTP/2 is a binary protocol, which is based on the "frame" structure design, which improves many HTTP/1.1 pain points. Here are some of the most commonly talked about improvements:

  • Multiplexed stream

  • Header compression

  • Resource priority and dependency settings

  • Server push

  • flow control

  • Reset message

Each item listed above is worthy of in-depth and detailed research. Here, we will only conduct in-depth study on the realization of the "multiplexing" function.

2. "Multiplexing" principle analysis

2.1 What is multiplexing?

There is a picture on the Internet that can clearly explain this problem:

The request-response model of the HTTP/1.1 protocol is familiar to everyone. We use "HTTP message" to represent a request-response process, then the message in HTTP/1.1 is "Pipeline serialization": Only after one message is completed, can the next message be carried out; while multiple messages in HTTP/2 are intertwined, which undoubtedly improves the efficiency of "communication". This is multiplexing: on an HTTP connection, multiple "HTTP messages" work at the same time.

2.2 Why can't HTTP/1.1 achieve "multiplexing"?

The simple answer is: HTTP/2 is a protocol based on binary "frames", and HTTP/1.1 is a protocol based on "text segmentation" analysis.
Look at an HTTP/1.1 simple GET request example:

GET / HTTP/1.1
Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
Accept-Encoding:gzip, deflate, br
Accept-Language:zh-CN,zh;q=0.9,en;q=0.8
Cache-Control:max-age=0
Connection:keep-alive
Cookie:imooc_uuid=b2076a1d-6a14-4cd5-91b0-17a9a2461cf4; imooc_isnew_ct=1517447702; imooc_isnew=2; zg_did=%7B%22did%22%3A%20%221662d799f3f17d-0afe8166871b85-454c092b-100200-1662d799f4015b%22%7D; loginstate=1; apsid=Y4ZmEwNGY3OTUwMTdjZTk0ZTc4YzBmYThmMDBmZDYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANDEwNzI4OQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA5NTMzNjIzNjVAcXEuY29tAAAAAAAAAAAAAAAAAAAAADBmNmM5MzczZTVjMTk3Y2VhMDE2ZjUxNmQ0NDUwY2IxIDPdWyAz3Vs%3DYj; Hm_lvt_fb538fdd5bd62072b6a984ddbc658a16=1541222935,1541224845; Hm_lvt_f0cfcccd7b1393990c78efdeebff3968=1540010199,1541222930,1541234759; zg_f375fe2f71e542a4b890d9a620f9fb32=%7B%22sid%22%3A%201541297212384%2C%22updated%22%3A%201541297753524%2C%22info%22%3A%201541222929083%2C%22superProperty%22%3A%20%22%7B%5C%22%E5%BA%94%E7%94%A8%E5%90%8D%E7%A7%B0%5C%22%3A%20%5C%22%E6%85%95%E8%AF%BE%E7%BD%91%E6%95%B0%E6%8D%AE%E7%BB%9F%E8%AE%A1%5C%22%2C%5C%22%E5%B9%B3%E5%8F%B0%5C%22%3A%20%5C%22web%5C%22%7D%22%2C%22platform%22%3A%20%22%7B%7D%22%2C%22utm%22%3A%20%22%7B%7D%22%2C%22referrerDomain%22%3A%20%22%22%2C%22cuid%22%3A%20%22Jph3DQ809OQ%2C%22%7D; PHPSESSID=h5jn68k1fcaadn61bpoqa9hch2; cvde=5be7a057c314b-1; IMCDNS=1
Host:www.imooc.com
Referer:https://www.imooc.com/
Upgrade-Insecure-Requests:1
User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36

The above is the text format of the HTTP/1.1 request message: Separate the content of each key:value with a newline character. It does not require high technology to parse this data. On the contrary, it is often slow and error-prone. The "server" needs to continuously read in bytes until it encounters a separator (here refers to a newline character, which may be represented by \n or \r\n in the code). This parsing method is feasible, and HTTP/1.1 has been It has been widely used for more than 20 years, and this has been done countless times, and the problem has always existed:

  • Only one request or response can be processed at a time, because the data that divides the message with a separator cannot stop parsing before it is completed.

  • It is impossible to predict how much memory is needed to parse this kind of data, which will put a lot of pressure on the "server" because it does not know how large a "buffer" should be read in a line of content to be parsed, in order to ensure parsing efficiency and speed Under the premise: how to allocate memory?

2.3 HTTP/2 frame structure design and multiplexing implementation

As mentioned earlier: HTTP/2 design is based on "binary frames". This design is undoubtedly a kind of "super art" because it achieves one purpose: everything is predictable and everything is controllable.
The frame is a data unit, which realizes the encapsulation of the message. The following is the frame structure of HTTP/2:

different information is stored in the bytes of the frame, the first 9 bytes are the same for each frame, the "server" only needs to parse these words when parsing the HTTP/2 data frame Section, you can accurately know how many bytes are expected in the entire frame to process information. Let's first understand the information stored in each field in the frame:

name length description
Length 3 bytes Indicates the length of the frame load, the default maximum frame size is 2^14
Type 1 byte The type of the current frame, which will be introduced below
Flags 1 byte Identification of specific frames
R First place Reserved bit, no need to set, otherwise it may bring serious consequences
Stream Identifier 31st place Unique ID for each stream
Frame Payload Not fixed The length of the real frame, the real length is set in Length

If you use HTTP/1.1, you need to send the previous request before you can send the next one; because HTTP/2 is framed, requests and responses can be interleaved or even reused.
In order to be able to send different "data information" and transfer different content through frame data, 10 different types of frames are defined in HTTP/2. The "frame" type can be set in the Type field of the above table. The following table shows the frame types of HTTP/2:

name ID description
DATA 0x0 The core content of the transport stream
HEADERS 0x1 Contains HTTP headers, and optional priority parameters
PRIORITY 0x2 Indicate or change the priority and dependency of the stream
RST_STREAM 0x3 Allow one end to stop the flow (usually due to errors)
SETTINGS 0x4 Negotiate connection-level parameters
PUSH_PROMISE 0x5 Prompt the client to push something on the server
PING 0x6 Test connection availability and round trip delay (RTT)
GOAWAY 0x7 Tell the other end that the current end is over
WINDOW_UPDATE 0x8 Negotiate how many bytes to receive at one end (for flow control)
CONTINUATION 0x9 Used to expand the HEADER data block

With the above understanding of HTTP/2 frames, we can explain how multiplexing is achieved, but before that, let’s first understand the concept of "streaming": independent, bidirectional frames on HTTP/2 connections Sequence exchange. The stream ID (6-9 bytes in the frame header) is used to identify the stream to which the frame belongs.
The following two figures respectively show the "multiplexing" process of the POST request data stream on the HTTP/2 protocol, which is easy to see:

3. More features and introduction

Due to the design of "frames" in HTTP/2 messages, the client and server can learn more about each other during the communication process. Let's briefly talk about other important features, which can be regarded as a learning guide direction.

3.1 Flow control (sliding window)

One of the new features of HTTP/2 is flow-based flow control. Unlike HTTP/1.1, as long as the client can process it, the server will send data as fast as possible. HTTP/2 provides the client with the ability to adjust the transmission speed (the server can also). The WINDOW_UPDATE frame is used to accomplish this. Each frame tells the other party how many bytes the sender wants to receive, and it will send a WINDOW_UPDATE frame to indicate its updated byte processing capability.

3.2 Set resource priority and dependency

An important feature of the stream is that you can set the priority and the dependency of the resource data. HTTP/2 can achieve these functions through stream dependencies. Through the HEADERS frame and the PRIORITY frame, the client can clearly tell the server what it needs most. This is achieved by declaring dependencies and weights.

  • The dependency relationship provides the client with the ability to tell the server which resources should be transmitted preferentially by indicating the dependence of certain objects on other objects.

  • The weight allows the client to tell the server how to specifically determine the priority of objects with common dependencies.

3.3 Server push

There is a famous saying in "The Art of War by Sun Tzu": "Before soldiers and horses arrive, food and grass go first." The server push function can realize such a function. When the page has not started to request specific resources, the server has already pushed some resources (like css and js) to the client. When the browser is about to render the page, the resource is already in the cache, which sounds like a cool thing, but it is actually the case. The server push is realized through the PUSH_PROMISE frame. Of course, the implementation details are very complicated, and interested students can study it.
The "multiplexing" problem of HTTP/2 has been clarified, and some new features have been introduced. Of course, if you want to understand some principles of HTTP/2, there are too many things to read and practice. For example, the "header compression" algorithm HPACK is one of the key elements of HTTP/2. It is the long-term research result of the HTTP/2 development team. Its ideological content is especially worth learning. The things designed in this section are just the tip of the iceberg in the HTTP/2 protocol. RFC7540 can help you fully understand all aspects of the protocol.

Guess you like

Origin blog.csdn.net/github_38885296/article/details/103397056