點擊上方“JavaEdge”,關注公衆號
RPC框架主要組成
通信框架
通信協議
序列化和反序列化格式
1 分類
RPC框架主要分爲:
1.1 綁定語言平臺
1.1.1 Dubbo
國內最早開源的RPC框架,由阿里巴巴公司開發並於2011年末對外開源,僅支持Java
架構
Consumer 服務消費者
Provider 服務提供者
Registry 註冊中心
Monitor是監控系統
交互流程
Consumer通過Registry獲取到Provider節點
再通過Dubbo的客戶端SDK與Provider建立連接,併發起調用
Provider通過Dubbo的服務端SDK接收到Consumer請求
處理後再把結果返回給Consumer
服務消費者、提供者都需引入Dubbo的SDK纔來完成RPC調用,因爲Dubbo是用Java實現,所以要求服務消費者、提供者也都必須用Java。
主要實現
默認採用Netty作爲通信框架
除了支持私有的Dubbo協議外,還支持RMI、Hession、HTTP、Thrift
支持多種序列化格式,比如Dubbo、Hession、JSON、Kryo、FST
1.1.2 Motan
微博內部使用的RPC框架,於2016年對外開源,僅支持Java。
架構
與Dubbo類似,都要在Client端(服務消費者)和Server端(服務提供者)引入SDK
register
和註冊中心交互,包括註冊服務、訂閱服務、服務變更通知、服務心跳發送等功能。Server端會在系統初始化時通過register模塊註冊服務,Client端會在系統初始化時通過register模塊訂閱到具體提供服務的Server列表,當Server列表發生變更時也由register模塊通知Client。protocol
用來進行RPC服務的描述和RPC服務的配置管理,這一層還可以添加不同功能的filter用來完成統計、併發限制等功能。serialize
將RPC請求中的參數、結果等對象進行序列化與反序列化,即進行對象與字節流的互相轉換,默認使用對Java更友好的Hessian 2進行序列化。transport
用來進行遠程通信,默認使用Netty NIO的TCP長鏈接方式。cluster
Client端使用的模塊,cluster是一組可用的Server在邏輯上的封裝,包含若干可以提供RPC服務的Server,實際請求時會根據不同的高可用與負載均衡策略選擇一個可用的Server發起遠程調用。
1.1.3 Spring Cloud
國外Pivotal公司2014年對外開源的RPC框架,僅支持Java,使用最廣。
是爲了解決微服務架構中服務治理而提供的一系列功能的開發框架,它是完全基於Spring Boot進行開發的,Spring Cloud利用Spring Boot特性整合了開源行業中優秀的組件,整體對外提供了一套在微服務架構中服務治理的解決方案。
架構
交互流程
請求統一通過API網關Zuul來訪問內部服務,先經過Token進行安全認證
通過安全認證後,網關Zuul從註冊中心Eureka獲取可用服務節點列表
從可用服務節點中選取一個可用節點,然後把請求分發到這個節點
整個請求過程中,Hystrix組件負責處理服務超時熔斷,Turbine組件負責監控服務間的調用和熔斷相關指標,Sleuth組件負責調用鏈監控,ELK負責日誌分析
選型
Spring Cloud不僅提供了基本的RPC框架功能,還提供了服務註冊組件、配置中心組件、負載均衡組件、斷路器組件、分佈式消息追蹤組件等一系列組件,稱爲“Spring Cloud全家桶”。如果你不想自己實現以上這些功能,那麼Spring Cloud基本可以滿足你的全部需求。而Dubbo、Motan基本上只提供了最基礎的RPC框架的功能,其他微服務組件都需要自己去實現。
不過由於Spring Cloud的RPC通信採用了HTTP協議,相比Dubbo和Motan所採用的私有協議來說,在高併發的通信場景下,性能相對要差一些,所以對性能有苛刻要求的情況下,可以考慮Dubbo和Motan。
1.2 跨語言平臺
1.2.1 gRPC
Google於2015年對外開源的跨語言RPC框架。
支持C++、Java、Python、Go、Ruby、PHP、Android Java、Objective-C。
原理
通過IDL(Interface Definition Language)文件定義服務接口的參數和返回值類型,然後通過代碼生成程序生成服務端和客戶端的具體實現代碼,這樣在gRPC裏,客戶端應用可以像調用本地對象一樣調用另一臺服務器上對應的方法。
特性
通信協議採用HTTP2,因其提供了連接複用、雙向流、服務器推送、請求優先級、首部壓縮等機制,所以在通信過程中可以節省帶寬、降低TCP連接次數、節省CPU,尤其對於移動端應用來說,可以幫助延長電池壽命
IDL使用了ProtoBuf,ProtoBuf是由Google開發的一種數據序列化協議,它的壓縮和傳輸效率極高,語法也簡單,所以被廣泛應用在數據存儲和通信協議上
多語言支持,能夠基於多種語言自動生成對應語言的客戶端和服務端的代碼。
1.2.2 Thrift
最初是由Facebook開發的內部系統跨語言的RPC框架,2007年貢獻給了Apache。輕量級的跨語言RPC通信方案,支持多達25種編程語言。爲了支持多種語言,跟gRPC一樣,Thrift也有一套自己的接口定義語言IDL,可以通過代碼生成器,生成各種編程語言的Client端和Server端的SDK代碼,這樣就保證了不同語言之間可以相互通信。
架構
特性
序列化格式
Binary、Compact、JSON、Multiplexed等。通信方式
Socket、Framed、File、Memory、zlib等。服務端支持多種處理方式
Simple 、Thread Pool、Non-Blocking等。
選型
那麼涉及跨語言的服務調用場景,到底該選擇gRPC還是Thrift呢?
從成熟度上來講,Thrift因爲誕生的時間要早於gRPC,所以使用的範圍要高於gRPC,在HBase、Hadoop、Scribe、Cassandra等許多開源組件中都得到了廣泛地應用。而且Thrift支持多達25種語言,這要比gRPC支持的語言更多,所以如果遇到gRPC不支持的語言場景下,選擇Thrift更合適。
但gRPC作爲後起之秀,因爲採用了HTTP/2作爲通信協議、ProtoBuf作爲數據序列化格式,在移動端設備的應用以及對傳輸帶寬比較敏感的場景下具有很大的優勢,而且開發文檔豐富,根據ProtoBuf文件生成的代碼要比Thrift更簡潔一些,從使用難易程度上更佔優勢,所以如果使用的語言平臺gRPC支持的話,建議還是採用gRPC比較好。
總結
所以若你的業務場景僅一種語言,可選擇跟語言綁定的RPC框架
如果涉及多個語言平臺之間的相互調用,必須選擇跨語言平臺的RPC框架。
支持多語言是RPC框架未來的發展趨勢。正是基於此判斷,各個RPC框架都提供了Sidecar組件來支持多語言平臺之間的RPC調用。
Dubbo也引入Sidecar組件來構建Dubbo Mesh提供多語言支持,如 dubbo-go。
Motan也開源了其內部的Sidecar組件:Motan-go,目前支持PHP、Java語言之間的相互調用。
Spring Cloud也提供了Sidecar組件spring-cloud-netflix-sideca,可以讓其他語言也可以使用Spring Cloud的組件。
所以語言不會成爲使用上面這幾種RPC框架的約束,而gRPC和Thrift雖然支持跨語言的RPC調用,但是因爲它們只提供了最基本的RPC框架功能,缺乏一系列配套的服務化組件和服務治理功能的支撐,所以使用它們作爲跨語言調用的RPC框架,就需要自己考慮註冊中心、熔斷、限流、監控、分佈式追蹤等功能的實現,不過好在大多數功能都有開源實現,可以直接採用。
往期推薦
目前交流羣已有 800+人,旨在促進技術交流,可關注公衆號添加筆者微信邀請進羣
喜歡文章,點個“在看、點贊、分享”素質三連支持一下~
本文分享自微信公衆號 - JavaEdge(Java-Edge)。
如有侵權,請聯繫 [email protected] 刪除。
本文參與“OSC源創計劃”,歡迎正在閱讀的你也加入,一起分享。