gRPC 是什麼?一個「遠端」卻「像本地」的呼叫
明明在跟另一台伺服器對話,寫起來卻像呼叫自己程式裡的一個函式——這件魔術是怎麼變的
先拆一個看似矛盾的名字
當你把一個大系統拆成一堆各司其職的小服務——這種做法叫 微服務架構(microservice architecture)——這些服務常常被部署在不同的伺服器上。訂單服務在一台機器、付款服務在另一台,它們之間要合作,就得透過網路互相「喊話」。
問題來了:跨機器的網路溝通,本來是件很囉唆的事——你得自己開連線、把資料打包成能在網路上傳的格式、送出去、等回應、再把回來的東西拆開還原。RPC(Remote Procedure Call,遠端程序呼叫) 的目標,就是把這一整串麻煩藏起來,讓你「呼叫遠端服務」寫起來,跟「呼叫自己程式裡的一個函式」幾乎一模一樣。
把它想成打國際電話:實際上訊號要繞過半個地球、經過無數交換機(這是 remote 的部分),但你手上做的事,就只是按幾個號碼、拿起話筒講話(這是 local 的體感)。中間所有的轉接、編碼、傳輸,電話系統都幫你藏起來了。RPC 對「呼叫遠端服務」做的,正是同一件事。
直接讀原文:remote 與 local 的那句定義
這段是 ByteByteGo 對 RPC 命名由來、以及「使用者角度像本地呼叫」的原話。原文放左邊,白話導讀放右邊。
RPC(遠端程序呼叫)之所以叫「remote(遠端)」,是因為在微服務架構下,服務被部署到不同的伺服器上,而它讓這些遠端服務之間得以互相溝通。
但從使用者(也就是寫程式的人)的角度看,它用起來就像在呼叫一個本地函式。
下面那張圖,說明的就是 gRPC 整體的資料流。
「remote」講的是物理事實——服務真的散在不同機器上;「像 local function call」講的是開發體驗——你不用管網路那攤爛事。這兩件事同時成立,靠的就是 gRPC 在中間默默做掉的所有工。這一整套「默默做掉的工」,就是模組 2 那張資料流圖要拆給你看的東西。
從 RPC 到 gRPC:多了哪三樣關鍵配料
RPC 是個概念,而 gRPC 是它其中一套很受歡迎的實作。要看懂模組 2 的資料流,你只需要先記住原文點名的三樣配料:
gRPC 不像常見的 REST API 那樣傳「人看得懂」的 JSON 文字,而是把資料編碼成緊湊的 二進位(binary)位元組。體積更小、機器解析更快。
封包透過 HTTP/2 這個較新、經過網路優化的傳輸協定送出,效率比舊的 HTTP/1.1 好。gRPC 就是建在 HTTP/2 之上的。
stub 是 gRPC 自動幫你生出來的一小段「代理程式碼」。你呼叫它就像呼叫本地函式,它在背後偷偷把參數編碼、送到網路上。這正是「像 local」的體感來源。
原文說:比 JSON 快 5 倍
把「二進位編碼」和「HTTP/2 網路優化」這兩樣配料加在一起,就得到 gRPC 最常被引用的一句賣點。原文是這樣寫的:
因為採用了二進位編碼,加上網路層面的優化,據說 gRPC 比 JSON 快上 5 倍。
原文用的是「is said to be 5X faster」——「據說」快 5 倍,而不是一個掛保證的絕對數字。實際加速多少會依資料大小、網路狀況而變。真正該記住的因果是:二進位比文字小又好解析、HTTP/2 比 HTTP/1.1 有效率,兩者疊加所以更快。至於是不是剛好 5 倍,那是原文引述的說法,不是鐵律。
小試身手
看懂這一格,你就抓到 gRPC 的核心觀念了。來兩題:
三樣配料都認識了,接下來把它們串起來——原文那張圖的 Step 1 到 Step 14,一個 REST 請求怎麼變成二進位、飛過網路、再變回結果。往下捲,按「下一步」跟著封包走。
跟著一次呼叫走完全程:gRPC 的資料流
一個 REST 請求怎麼變成二進位、飛過網路、被另一台伺服器執行,再原路變回結果——原文 Step 1 到 14,這裡走一遍給你看
先認識這趟旅程的三個角色
原文的資料流圖裡有幾個固定角色。先把它們認清楚,等下看動畫才不會迷路:
發起請求的那一方,例如使用者的瀏覽器或 App。它送出的是一般的 REST 呼叫,請求主體通常是 JSON。
收下 client 的 REST 呼叫。在這趟旅程裡,它同時扮演 gRPC client:負責把請求轉換、編碼成二進位,再對付款服務發出 gRPC 呼叫。
另一台伺服器上的服務,扮演 gRPC server:從網路收下封包、解碼、真正執行伺服器端的應用程式邏輯,再把結果原路送回。
留意一個容易搞混的點:order service 對使用者來說是伺服器(它收 REST 請求),但對 payment service 來說它是客戶端(它發 gRPC 呼叫)。同一個服務在不同關係裡扮演不同角色,這在微服務裡非常常見。中間那條網路,我們用一個 HTTP/2 傳輸層節點來代表。
招牌互動:按「下一步」,跟著封包走一趟
下面把原文的 Step 1–14 壓縮成 8 個關鍵步驟,順序完全忠於原文:從 client 發 REST 請求,到訂單服務編碼、經 HTTP/2 送出、付款服務執行、結果原路解碼送回。按「下一步」,留意兩件事:編碼/解碼總是成對出現(去程編、回程解),以及封包過網路那一步走的是 HTTP/2。
看出那條對稱線了嗎?去程:order service 編碼 → 過網路 → payment service 解碼、執行。回程:payment service 把結果編碼 → 過同一條網路 → order service 解碼、交還 client。編碼與解碼永遠成對,就像寄信要封信封、收信要拆信封。這正是 gRPC 把「網路那攤事」藏起來的具體樣貌。
動手對對看:每一步是誰做的?
把下面四個動作,拖到負責它的角色上。想不起來就往上滑,再看一次動畫。
小試身手
整趟資料流都跟上了。來兩題收尾:
原文結尾丟出兩個問題:你在自己的專案裡用過 gRPC 嗎?它有哪些限制?想一想——例如它傳的是二進位,人不容易直接讀來除錯;瀏覽器也不能原生直接發 gRPC 呼叫(常需要 gRPC-Web 這類橋接)。這些取捨,正是你決定「這裡該用 gRPC 還是普通 REST」時要權衡的。