Dubbo 3.0 前瞻之:常用協議對比及 RPC 協議新形態探索


頭圖.png

作者 | 郭浩(項升)  阿里巴巴經濟體 RPC 框架負責人

導讀:Dubbo 社區策划了【Dubbo 雲原生之路】系列文章,和大家一起回顧 Apache Dubbo 產品和社區的發展,並展望未來發展。系列文章主要涵蓋 Dubbo 技術解讀、社區運營、應用案例解析三大部分。本文為系列第 4 篇。

前言

協議是 RPC 的基礎。數據在連接上以什么格式傳輸,服務端如何確定收到請求的大小,同一個連接上能不能同時存在多個請求,請求如果出錯了應該怎么響應……這些都是需要協議解決的問題。

從定義上講,協議通過定義規則、格式和語義來約定數據如何在網絡間傳輸。RPC 需要通信的兩端都能夠識別同一種協議。數據在網絡上以比特流的方式傳輸,如果本端的協議對端不識別,對端就無法從請求中獲取到有用信息,就會出現雞同鴨講的情況,無法實現上層的業務需求。

1.png

一個簡單的協議需要定義數據交換格式,協議格式和請求方式。

數據交換格式在 RPC 中也叫做序列化格式。常用的序列化有 JSON / Protobuf / Hessian 等,評價序列化優劣一般從三個維度:

  • 序列化后的字節數組大小
  • 序列化和反序列化速度
  • 序列化后的可讀性

協議在選取序列化方式時,按照具體的需求在這三個維度中互相取舍。序列化后的數組越小,越節省網絡流量,但序列化過程可能更消耗時間。JSON\XML 這類基於文本的序列化方式往往更容易被開發者接受,因為相比於一連傳的字節數組,文本更容易被理解,在各層設備中都能比較容易的識別,但可讀性提高的后果是性能大幅降低。

協議格式是和 RPC 框架緊密相關的,按照功能划分有兩種:

  • 一種是緊湊型協議,只提供用於調用的簡單元數據和數據內容;
  • 另外一種是復合型協議,會攜帶框架層的元數據用來提供功能上的增強,這類協議的一個代表就是 RSocket。

請求方式和協議格式息息相關,常見的請求格式有同步 Request/Response 和異步 Request/Response,區別是客戶端發出一個請求后,是否需要同步等待響應返回。如果不需要等待響應,一個鏈接上就可以同時存在多個未完成的請求,這也被叫做多路復用。另外的請求模型有 Streaming ,在一次完整的業務調用中存在多次 RPC,每次都傳輸一部分數據,適合流數據傳輸。

有了這三個基本約定,就能實現一個簡單的 RPC 協議了。

2.png

Dubbo3 的一個核心內容就是定義下一代 RPC 協議。除了基礎的通信功能,新協議還應該具有以下特性:

  • 統一的跨語言二進制格式
  • 支持 Streaming 和應用層全雙工調用模型
  • 易於擴展
  • 能夠被各層設備識別

這里我們對比一些常用的協議,來探索新協議的形態。

HTTP/1.1

HTTP/1.1 應該是應用最廣泛的協議,簡單清晰的語法,跨語言以及對原生移動端的支持都讓其成為了事實上最被廣泛接受的 RPC 方案。

然而從 RPC 協議的訴求上講, HTTP1.1 主要有以下幾個問題

  • 隊頭阻塞(HOL)導致其在單連接的性能低下,盡管支持了 pipeline 但仍無法避免響應按序返回;

  • 基於文本的協議每次請求都會重復攜帶很多繁雜無用的頭部信息,浪費帶寬影響性能;

  • 純粹的 Request/Response 請求模型,無法實現 Server Push,只能依靠客戶端輪詢,同樣 Streaming 的全雙工也是不安全的。

3.png

RESP

RESP 是 Redis 使用的通信協議,其簡潔易於理解的格式也助力了 Redis 各語言客戶端的快速發展。但是這種類似 HTTP/1.1 的協議也存在着同樣的性能問題。

  • 序列化表達能力弱,通常還需要借助其他序列化方式輔助,然而協議中又不支持設置特定序列化方式,只能依靠客戶端約定;

  • 同樣存在隊頭阻塞問題,pipeline 無法從根本上解決單連接性能問題;

  • Pub/Sub 在單連接情況下也有數量瓶頸。

Dubbo2.0

Dubbo2.0 協議直接定義在 TCP 傳輸層協議上,為協議功能定義提供了最大的靈活性,但同時也正是因為這樣明顯的靈活性優勢,RPC 協議普遍都是定制化的私有協議。

Dubbo 協議體 Body 中有一個可擴展的 attachments 部分,這給 RPC 方法之外額外傳遞附加屬性提供了可能,是一個很好的設計。但是類似的 Header 部分,卻缺少類似的可擴展 attachments,這點可參考 HTTP 定義的 Ascii Header 設計,將 Body Attachments 和 Header Attachments 做職責划分。

  • Body 協議體中的一些 RPC 請求定位符如 Service Name、Method Name、Version 等,可以提到 Header 中,和具體的序列化協議解耦,以更好的被網絡基礎設施識別或用於流量管控;

  • 擴展性不夠好,欠缺協議升級方面的設計,如 Header 頭中沒有預留的狀態標識位,或者像 HTTP 有專為協議升級或協商設計的特殊 packet;

  • 在 Java 版本的代碼實現上,不夠精簡和通用。如在鏈路傳輸中,存在一些語言綁定的內容;消息體中存在冗余內容,如 Service Name 在 Body 和 Attachments 中都存在。

HTTP/2.0

HTTP/2.0 保留了 HTTP/1 的所有語義,在保持兼容的同時,在通信模型和傳輸效率上做了很大的改進,主要也是為了解決 HTTP/1 中的問題。

  • 支持單條鏈路上的 Multiplexing,相比於 Request - Response 獨占鏈路,基於 Frame 實現更高效利用鏈路,StreamId 提供了上下文狀態,client 可以根據 StreamId 支持亂序 Response 返回;

  • 頭部壓縮 HPACK,基於靜態表和動態表實現了 Header 緩存,減少傳輸數據量;

  • Request - Stream 語義,原生支持 Server Push 和 Stream 數據傳輸;

  • Binary Frame,二進制分幀,可以單獨處理 Header 和 Data。

HTTP/2.0 雖然克服了以上問題,但也存在着一些爭議點,比如在 TCP 的上層進行流量控制的必要性,以及對 HTTP 語義通過 HPACK 兼容是否過於繁瑣復雜。

gRPC

相比較於一些框架將應用層協議構建在裸 TCP 上,gRPC 選擇了 HTTP/2.0 作為傳輸層協議。通過對 Header 內容和 Payload 格式的限定實現上層協議功能。

下面是 gRPC 的一些設計理念:

  • Coverage & Simplicity,協議設計和框架實現要足夠通用和簡單,能運行在任何設備之上,甚至一些資源首先的如 IoT、Mobile 等設備;

  • Interoperability & Reach,要構建在更通用的協議之上,協議本身要能被網絡上幾乎所有的基礎設施所支持;

  • General Purpose & Performant,要在場景和性能間做好平衡,首先協議本身要是適用於各種場景的,同時也要盡量有高的性能;

  • Payload Agnostic,協議上傳輸的負載要保持語言和平台中立;

  • Streaming,要支持 Request - Response、Request - Stream、Bi-Steam 等通信模型;

  • Flow Control,協議自身具備流量感知和限制的能力;

  • Metadata Exchange,在 RPC 服務定義之外,提供額外附加數據傳輸的能力。

在這樣的設計理念指導下,gRPC 最終被設計為一個跨語言、跨平台、通用的協議。功能上基本已經完全具備或可以輕易擴展出需要的新功能。然而我們知道,軟件工程沒有銀彈,相比較於裸 TCP 專有協議,極限性能上 gRPC 肯定是要差一些。但是對大部分應用來說,相比較於 HTTP/1.1 的協議,gRPC/HTTP2 已經在性能上取得了很大的進步,同時又兼顧了可讀性。

序列化上,gRPC 被設計成保持 payload 中立,但實際的跨語言場景需要一個強規范的接口定義語言來保證序列化結果的一致。在 gRPC 的官方實現中,protobuf 和 json 分別用來支持性能場景和開發效率場景。從序列化方式的選擇到協議的各維度比較,基於 gRPC 擴展出新的協議是最優的選擇。

Dubbo3.0

Dubbo3.0 的協議基於 gRPC ,在應用層、異常處理、協議層負載均衡支持和 Reactive 支持上提供了擴展。主要有三個目標:

  • 在分布式大規模集群場景下,提供更完善的負載均衡,以獲取更高性能和保證穩定性;

  • 支持 tracing/monitoring 等分布式標准擴展,支持微服務標准化以及平滑遷移;

  • Reactive 語義在協議層增強,能夠提供分布式 back-pressure 能力和更完善的 Streaming 支持。

除了協議層的支持,Dubbo3.0 新協議還包括易用性方面的支持,包括同時支持 IDL compiler 和 Annotation Compiler。客戶端將更完善地支持原生異步回調、Future 異步和同步調用,服務端將使用非反射調用,這十分顯著地提升了客戶端和服務端性能。從用戶遷移的角度,Dubbo 框架將提供平滑的協議升級支持,力求盡可能少的改造代碼或配置就能帶來成倍的性能提升。

系列文章:

總結

本文介紹了 RPC 協議的基礎概念,比較了常用的一些協議,並在這些協議的優劣對比后提出了 Dubbo3.0 協議。Dubbo3.0 協議將在易用性、跨平台、跨語言、高性能等方面取得更大的領先。預計在 2021 年 3 月,Dubbo3.0 協議將完整支持,請大家拭目以待。

阿里巴巴雲原生關注微服務、Serverless、容器、Service Mesh 等技術領域、聚焦雲原生流行技術趨勢、雲原生大規模的落地實踐,做最懂雲原生開發者的公眾號。”


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM