Introduction
An important improvement of HTTP2 over http1.1 is flow control. Why is there flow control? This is because regardless of the protocol, the client and server have a buffer to temporarily store data that cannot be processed temporarily when receiving data, but the size of the buffer is limited, so there may be a buffer Overflow situations, such as uploading a large picture from the client to the server, may cause the buffer on the server to overflow and cause some additional data packets to be lost.
In order to avoid buffer overflow, various HTTP protocols provide certain solutions.
In HTTP1.1, flow control relies on the underlying TCP protocol. When a connection is established between the client and the server, the system default settings are used to establish a buffer. When data is being communicated, it will tell the other party the size of its receiving window, which is the remaining free space in the buffer. If the receiving window size is zero, it means that the receiver's buffer is full, and the sender will no longer send data until the client clears its internal buffer, and then requests to resume data transmission.
HTTP2 uses the client and server applications to transmit buffer size messages. By controlling the data flow at the application layer, each application can control the size of the flow by itself, thereby achieving higher connection efficiency.
This article will introduce netty's support for http2 flow control.
Flow control in http2
In the introduction, we also mentioned that traditional HTTP 1.1 uses the flow control mechanism at the bottom of the system, specifically TCP flow control. But TCP's flow control is not enough in HTTP2. Because HTTP2 uses a multiplexing mechanism, a TCP connection can have multiple http2 connections. So for http2, TCP's flow control mechanism is too rough and not fine enough.
Therefore, in HTTP2, a more refined flow control mechanism is implemented, which allows the client and server to implement their own data flow and connection-level flow control.
The specific process is like this. When the client and server establish a connection, Http2SettingsFrame will be sent. This settings frame contains SETTINGS_INITIAL_WINDOW_SIZE, which is the window size of the sender and is used for Stream level flow control. The default value of the flow control window is set to 65,535 bytes, but the receiver can modify it, and the maximum value is 2^31-1 bytes.
After the initial windows size is established, for the receiver, each time the sender sends a data frame, it will reduce the size of the window, and each time the receiver sends a WINDOW_UPDATE frame, it will increase the size of the window to achieve the purpose of dynamic control. .
Netty's encapsulation of http2 flow control
Http2FlowController
From the above introduction, we know that http2 flow control is implemented through two aspects. The first aspect is the initialized Http2SettingsFrame, and the initial window size is controlled by setting SETTINGS_INITIAL_WINDOW_SIZE. The second aspect is to dynamically increase or decrease the size of the window in the subsequent WINDOW_UPDATE frame.
For netty, all this is encapsulated in the Http2FlowController class. Http2FlowController is an abstract class, which has two implementations, namely Http2LocalFlowController and Http2RemoteFlowController. They respectively represent the processing of inbound flow of DATA and outbound flow of DATA.
There are mainly 5 methods in Http2FlowController, namely:
- set channelHandlerContext: Bind flowcontrol to ChannelHandlerContext.
- set initialWindowSize: Initialize the window size, which is equivalent to setting SETTINGS_INITIAL_WINDOW_SIZE.
- get initialWindowSize: Returns the initial window size.
- windowSize: Get the current windowSize.
- incrementWindowSize: Increase the size of the flow control window.
Next, let's take a look at his two implementation classes, what are the differences.
Http2LocalFlowController
LocalFlowController is used to perform flow control on DATA frames sent from remote nodes. It has 5 main methods.
- set frameWriter: used to set the frame writer for sending WINDOW_UPDATE frames.
- receiveFlowControlledFrame: Receive inbound DATA frame and perform flow control on it.
- consumeBytes: Indicates that the application has consumed a certain number of bytes and can accept more data sent from remote nodes. Flow control can send WINDOW_UPDATE frame to reset the window size.
- unconsumedBytes: bytes received but not consumed.
- initialWindowSize: The initial window size of the given stream.
Http2RemoteFlowController
remoteFlowController is used to process outbound DATA frames sent to remote nodes. It provides 8 methods:
- get channelHandlerContext: Get the context of the current flow control.
- addFlowControlled: Add the flow control payload to the queue sent to the remote node.
- hasFlowControlled: Determine whether the current stream has FlowControlled frames in the queue.
- writePendingBytes: Write all pending data in the flow controller to the flow control limit.
- listener: Add listener to flow-controller.
- isWritable: Determine whether the stream has remaining bytes available for the flow control window.
- channelWritabilityChanged: Whether the writable state of the context has changed.
- updateDependencyTree: Update the dependency relationship between streams, because streams can have parent-child structures.
Use of flow control
The flowControl-related classes are mainly used in Http2Connection, Http2ConnectionDecoder, Http2ConnectionEncoder, and play a corresponding role when establishing an http2 connection.
Summarize
FlowControl is a relatively low-level concept in http2, and you should encounter it in the in-depth understanding of netty's http2 implementation.
This article has been included in http://www.flydean.com/29-netty-flowcontrol/
The most popular interpretation, the most profound dry goods, the most concise tutorial, and many tips you don't know are waiting for you to discover!
Welcome to pay attention to my official account: "Program those things", know technology, know you better!
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。