從文本到二進制:HTTP/2不止于性能,更是對HTTP/1核心語義的傳承與革新
云原生計算基金會(Cloud Native Computing Foundation,CNCF)是一個非盈利的開源組織,專注于推動云原生計算的發展和標準化。而gRPC(Google Remote Procedure Call)是由Google發起并開源的高性能、跨語言RPC框架。2017年,Google將gRPC項目捐贈給了CNCF,使其成為云原生生態的核心組件之一。gRPC與Kubernetes(容器編排)、Prometheus(監控)、Istio(服務網格)等CNCF項目深度集成,廣泛應用于微服務架構和云原生應用中,其重要性隨著云原生理念的普及而日益凸顯。
gRPC巧妙地結合了ProtoBuf、HTTP/2等成熟技術,為上述RPC三大問題提供了全面且標準化的解決方案。
1)數據表示:默認采用 ProtoBuf作為其IDL和高效的二進制序列化方案。
2)數據傳遞:建立在 HTTP/2 協議之上,利用其多路復用、流控、頭部壓縮等特性實現高效網絡通信。
3)方法約定:通過 ProtoBuf IDL (.proto 文件) 定義服務接口和消息結構。
HTTP/2協議

HTTP/2是HTTP/1.1的重大升級版,其設計源于Google的SPDY協議,并于2015年正式成為標準(RFC 7540)。HTTP/1.1雖應用廣泛,但其固有的性能瓶頸——如隊頭阻塞(Head-of-Line Blocking)、較高的連接建立延遲、低效的文本頭部傳輸——已難以滿足現代Web應用對高性能、低延遲的需求。HTTP/2旨在克服這些問題,顯著提升傳輸效率和用戶體驗。
與HTTP/1.1的純文本傳輸不同,HTTP/2引入了二進制分幀層 (Binary Framing Layer)。所有HTTP消息(請求/響應)都被封裝成一個個二進制編碼的幀 (Frame) 進行傳輸。這種設計不僅提高了處理效率和健壯性(解析二進制比文本更快更不容易出錯),還為多路復用(Multiplexing)、頭部壓縮(Header Compression)和服務器推送(Server Push)等高級特性奠定了基礎。
HTTP/2的核心架構包含以下幾個關鍵概念。
1)Connection(連接):一個TCP連接支持多個并發Stream,減少了HTTP/1.1中多個TCP連接的開銷和延遲。
2)Stream(流):獨立的雙向通信通道,用于傳輸一條或多條Message,避免了隊頭阻塞。
3)Message(消息):對應HTTP/1.1的請求或響應,由一個或多個Frame組成,使數據傳輸更靈活。
4)Frame(幀):最小的通信單位,采用二進制格式,包含元數據和有效載荷,用于客戶端與服務器間的信息傳遞。

幀結構
幀是一種長度前綴消息(Length-Prefixed-Message)。幀以固定的9字節作為幀頭,后面跟著變長的幀載荷(Frame Payload),幀頭包括如下公共字段:Type、Length、Flags, Stream Identifier。
+-----------------------------------------------+
| Length (24) |
+---------------+---------------+---------------+
| Type (8) | Flags (8) |
+-+-------------+---------------+-------------------------------+
|R| Stream Identifier (31) |
+=+=============================================================+
| Frame Payload (0...) ...
+---------------------------------------------------------------+
HTTP/2協議定義了10種不同類型的幀(Frame),其中通用格式包含以下幾個關鍵類型,這些類型共同定義了幀的行為和內容。
1)Length(長度):表示幀載荷(Frame Payload)的長度,以字節為單位。其最大長度為2^14(即16384字節),不包括幀頭的9個字節。
2)Type(類型):用于標識幀的類型。其中,DATA幀和HEADERS幀,分別對應于HTTP/1.1中的數據和頭部信息。其他幀類型還包括SETTINGS、PRIORITY、RST_STREAM等,用于實現協議的各種高級特性。
3)Flags(標志):該字段包含一組標志位,用于傳遞幀的附加控制信息。常用的標志位包括: END_HEADERS:表示當前幀是頭數據(Headers)的最后一幀,相當于HTTP/1.1中頭信息結束后的空行(“\r\n”);END_STREAM:表示當前幀是流(Stream)中最后一個幀,標志著單方向數據傳輸的結束(End of Stream, EOS),相當于HTTP/1.1中分塊傳輸編碼(Chunked Encoding)的結束標志(“0\r\n\r\n”);PRIORITY:用于指示流的優先級,幫助服務器和客戶端優化資源分配。
4)R(保留字段):該字段為保留位,目前未使用,必須設置為0。
5)Stream Identifier(流標識符):用于標識幀所屬的流(Stream)。每個流都有一個唯一的標識符,用于在同一個TCP連接中區分不同的并發流。流標識符的長度為31位,其中客戶端發起的流使用奇數標識符,服務器發起的流使用偶數標識符。
消息的語義兼容性
HTTP/2 協議與 HTTP/1盡可能保持兼容。從應用程序的角度來看,協議的功能基本沒有變化。為了實現這一點,HTTP/1的所有請求和響應語義被保留,雖然傳達那些語義的語法已經改變。
HTTP/1使用消息起始行(start-line)來傳達目標 URI,請求方法和響應的狀態代碼,而HTTP/2為此使用以“:”字符開頭的特殊字段(pseudo-header)來達到相同的目的。

可以看到在第一個請求中,前兩個頭通常類似與HTTP/1。
GET /resoure HTTP/1.1
Host: https://example.com
...
現在被拆分為一個標題框。
:method: GET
:scheme: https
:host: example.com
:path: /resource
...
而其余的頭則大致相同,都是lower-case字符。
HTTP/2嘗試盡可能地最小化有效載荷大小。它將壓縮與前一個請求中相同的頭。在HTTP/1中,一個連續的請求看起來像是針對不同資源的初始請求。
GET /otherResource HTTP/1.1
Host: https://example.org
...
而在HTTP/2中,對同一服務器的連續請求只需要:path頭部信息。
:path: /otherResource
因為所有其他頭部信息都被標記并壓縮緩存,并且可以通過“索引”進行還原。
未完待續
很高興與你相遇!如果你喜歡本文內容,記得關注哦!
本文來自博客園,作者:poemyang,轉載請注明原文鏈接:http://www.rzrgm.cn/poemyang/p/19061836
浙公網安備 33010602011771號