Remote Procedure Call (RPC)
核心概念
RPC 的目標:讓跨網路的函式呼叫,在程式碼層面看起來跟本地呼叫一模一樣。
你還是寫 k = add(i, j),背後的網路傳輸對你完全不可見。這個透明性靠 Stub 實現。
Stub
Stub 是一個代理(proxy):
- Client stub:坐落在 client 端,對 client 程式偽裝成真正的函式
- Server stub:坐落在 server 端,負責接收訊息並呼叫真正的函式
RPC 的完整流程(10 步)
以 k = add(i, j) 為例:
Client 端出發
- Client 程式用正常方式呼叫 client stub
- Client stub 把函式名稱和參數**打包(marshal)**成訊息
- Client OS 把訊息送往 server
網路傳輸
- Server OS 收到訊息,交給 server stub
Server 端執行
- Server stub **拆包(unmarshal)**還原參數,呼叫真正的
add() - Server 計算結果,回傳給 server stub
結果回傳
- Server stub 把結果打包成訊息,叫 server OS 傳回去
- Server OS 把訊息傳到 client OS
- Client OS 把訊息交給 client stub
- Client stub 拆包結果,直接 return 給 client 程式
對 client 程式而言,整個過程就像呼叫了一個本地函式。
RPC 的三個挑戰
1. 資料格式差異(XDR)
不同架構的電腦對資料的表示方式可能不同,最典型的是 big-endian vs little-endian——同樣的整數,bytes 在記憶體中的排列順序可能相反,直接傳原始 bytes 會解讀錯誤。
解法:用 XDR(External Data Representation) 格式,把資料轉成雙方都認識的中立格式再傳輸。
2. 可靠性(Exactly Once)
本地呼叫幾乎不會失敗,但網路通訊會:封包可能遺失、server 可能當機。
這引發一個微妙問題:如果 client 沒收到回應,是「server 還沒執行」還是「server 執行完但回應遺失」?兩種情況的處理方式完全不同。
| 語義 | 意義 |
|---|---|
| At most once | 最多執行一次(不保證有沒有執行到) |
| Exactly once | 剛好執行一次(RPC 的理想目標,但難以保證) |
3. 找到 Server 的 Port(Matchmaker / Rendezvous)
Port 不應寫死。OS 提供一個 matchmaker 服務:
1. Client 問 matchmaker:「RPC X 在哪個 port?」
2. Matchmaker 回傳 port 號 P
3. Client 向 port P 發送實際的 RPC 請求
4. Server daemon 處理請求並回傳結果