目錄
- 一、什麼是 RPC?
- 二、RPC 是如何通訊的?
- 三、為什麼要用 RPC?
- 四、常見RPC框架
一、什麼是 RPC?
- RPC 是指遠端過程呼叫,也就是說兩臺伺服器 A、B,一個應用部署在 A 伺服器上,想要呼叫 B 伺服器上應用提供的函式或方法,由於不在一個記憶體空間,不能直接呼叫,需要透過網路來表達呼叫的語義和傳達呼叫的資料。
二、RPC 是如何通訊的?
- 要解決通訊的問題,主要是透過在客戶端和伺服器之間建立 TCP 連線,遠端過程呼叫的所有交換的資料都在這個連線裡傳輸。連線可以是按需連線,呼叫結束後就斷掉,也可以是長連線,多個遠端過程呼叫共享同一個連線。
- 要解決定址的問題,也就是說,A 伺服器上的應用怎麼告訴底層的 RPC 框架,如何連線到 B 伺服器(如主機或 IP 地址)以及特定的埠,方法的名稱是什麼,這樣才能完成呼叫。比如基於 Web 服務協議棧的 RPC,就要提供一個 endpoint URI,或者是從 UDDI 服務上查詢。如果是 RMI 呼叫的話,還需要一個 RMI Registry 來註冊服務的地址。
- 當 A 伺服器上的應用發起遠端過程呼叫時,方法的引數需要透過底層的網路協議如 TCP 傳遞到 B 伺服器,由於網路協議是基於二進位制的,記憶體中的引數的值要序列化成二進位制的形式,也就是序列化(Serialize)或編組(marshal),透過定址和傳輸將序列化的二進位制傳送給 B 伺服器。
- B 伺服器收到請求後,需要對引數進行反序列化(序列化的逆操作),恢復為記憶體中的表達方式,然後找到對應的方法(定址的一部分)進行本地呼叫,然後得到返回值。
- 返回值還要傳送回伺服器 A 上的應用,也要經過序列化的方式傳送,伺服器 A 接到後,再反序列化,恢復為記憶體中的表達方式,交給 A 伺服器上的應用。
三、為什麼要用 RPC?
- 就是無法在一個程序內,甚至一個計算機內透過本地呼叫的方式完成的需求,比如比如不同的系統間的通訊,甚至不同的組織間的通訊。由於計算能力需要橫向擴充套件,需要在多臺機器組成的叢集上部署應用
四、常見RPC框架
功能 | Hessian | Montan | rpcx | gRPC | Thrift | Dubbo | Dubbox | Spring Cloud |
---|---|---|---|---|---|---|---|---|
開發語言 | 跨語言 | Java | Go | 跨語言 | 跨語言 | Java | Java | Java |
分散式(服務治理) | × | √ | √ | × | × | √ | √ | √ |
多序列化框架支援 | hessian | √(支援Hessian2、Json,可擴充套件) | √ | × 只支援protobuf) | ×(thrift格式) | √ | √ | √ |
多種註冊中心 | × | √ | √ | × | × | √ | √ | √ |
管理中心 | × | √ | √ | × | × | √ | √ | √ |
跨程式語言 | √ | ×(支援php client和C server) | × | √ | √ | × | × | × |
支援REST | × | × | × | × | × | × | √ | √ |
關注度 | 低 | 中 | 低 | 中 | 中 | 中 | 高 | 中 |
上手難度 | 低 | 低 | 中 | 中 | 中 | 低 | 低 | 中 |
運維成本 | 低 | 中 | 中 | 中 | 低 | 中 | 中 | 中 |
開源機構 | Caucho | Apache | Apache | Alibaba | Dangdang | Apache |
- 實際場景中的選擇
# Spring Cloud : Spring全家桶,用起來很舒服,只有你想不到,沒有它做不到。可惜因為釋出的比較晚,國內還沒出現比較成功的案例,大部分都是試水,不過畢竟有Spring作背書,還是比較看好。
# Dubbox: 相對於Dubbo支援了REST,估計是很多公司選擇Dubbox的一個重要原因之一,但如果使用Dubbo的RPC呼叫方式,服務間仍然會存在API強依賴,各有利弊,懂的取捨吧。
# Thrift: 如果你比較高冷,完全可以基於Thrift自己搞一套抽象的自定義框架吧。
# Montan: 可能因為出來的比較晚,目前除了新浪微博16年初發布的,
# Hessian: 如果是初創公司或系統數量還沒有超過5個,推薦選擇這個,畢竟在開發速度、運維成本、上手難度等都是比較輕量、簡單的,即使在以後遷移至SOA,也是無縫遷移。
# rpcx/gRPC: 在服務沒有出現嚴重效能的問題下,或技術棧沒有變更的情況下,可能一直不會引入,即使引入也只是小部分模組最佳化使用。