01

gRPC 是什麼?一個「遠端」卻「像本地」的呼叫

明明在跟另一台伺服器對話,寫起來卻像呼叫自己程式裡的一個函式——這件魔術是怎麼變的

先拆一個看似矛盾的名字

當你把一個大系統拆成一堆各司其職的小服務——這種做法叫 微服務架構(microservice architecture)——這些服務常常被部署在不同的伺服器上。訂單服務在一台機器、付款服務在另一台,它們之間要合作,就得透過網路互相「喊話」。

問題來了:跨機器的網路溝通,本來是件很囉唆的事——你得自己開連線、把資料打包成能在網路上傳的格式、送出去、等回應、再把回來的東西拆開還原。RPC(Remote Procedure Call,遠端程序呼叫) 的目標,就是把這一整串麻煩藏起來,讓你「呼叫遠端服務」寫起來,跟「呼叫自己程式裡的一個函式」幾乎一模一樣。

📞
為什麼叫「remote」,用起來卻「local」

把它想成打國際電話:實際上訊號要繞過半個地球、經過無數交換機(這是 remote 的部分),但你手上做的事,就只是按幾個號碼、拿起話筒講話(這是 local 的體感)。中間所有的轉接、編碼、傳輸,電話系統都幫你藏起來了。RPC 對「呼叫遠端服務」做的,正是同一件事。

直接讀原文:remote 與 local 的那句定義

這段是 ByteByteGo 對 RPC 命名由來、以及「使用者角度像本地呼叫」的原話。原文放左邊,白話導讀放右邊。

原文 · ByteByteGo RPC (Remote Procedure Call) is called “remote” because it enables communications between remote services when services are deployed to different servers under microservice architecture. From the user’s point of view, it acts like a local function call. The diagram below illustrates the overall data flow for gRPC.
白話翻譯

RPC(遠端程序呼叫)之所以叫「remote(遠端)」,是因為在微服務架構下,服務被部署到不同的伺服器上,而它讓這些遠端服務之間得以互相溝通。

但從使用者(也就是寫程式的人)的角度看,它用起來就像在呼叫一個本地函式。

下面那張圖,說明的就是 gRPC 整體的資料流。

💡
一句話抓住重點

「remote」講的是物理事實——服務真的散在不同機器上;「像 local function call」講的是開發體驗——你不用管網路那攤爛事。這兩件事同時成立,靠的就是 gRPC 在中間默默做掉的所有工。這一整套「默默做掉的工」,就是模組 2 那張資料流圖要拆給你看的東西。

從 RPC 到 gRPC:多了哪三樣關鍵配料

RPC 是個概念,而 gRPC 是它其中一套很受歡迎的實作。要看懂模組 2 的資料流,你只需要先記住原文點名的三樣配料:

🔢
二進位編碼

gRPC 不像常見的 REST API 那樣傳「人看得懂」的 JSON 文字,而是把資料編碼成緊湊的 二進位(binary)位元組。體積更小、機器解析更快。

🚄
走 HTTP/2

封包透過 HTTP/2 這個較新、經過網路優化的傳輸協定送出,效率比舊的 HTTP/1.1 好。gRPC 就是建在 HTTP/2 之上的。

📦
stub(樁)

stub 是 gRPC 自動幫你生出來的一小段「代理程式碼」。你呼叫它就像呼叫本地函式,它在背後偷偷把參數編碼、送到網路上。這正是「像 local」的體感來源。

原文說:比 JSON 快 5 倍

把「二進位編碼」和「HTTP/2 網路優化」這兩樣配料加在一起,就得到 gRPC 最常被引用的一句賣點。原文是這樣寫的:

原文 · ByteByteGo Because of binary encoding and network optimizations, gRPC is said to be 5X faster than JSON.
白話翻譯

因為採用了二進位編碼,加上網路層面的優化,據說 gRPC 比 JSON 快上 5 倍。

⚖️
注意原文的措辭:是「said to be」

原文用的是「is said to be 5X faster」——「據說」快 5 倍,而不是一個掛保證的絕對數字。實際加速多少會依資料大小、網路狀況而變。真正該記住的因果是:二進位比文字小又好解析、HTTP/2 比 HTTP/1.1 有效率,兩者疊加所以更快。至於是不是剛好 5 倍,那是原文引述的說法,不是鐵律。

小試身手

看懂這一格,你就抓到 gRPC 的核心觀念了。來兩題:

RPC 為什麼叫「remote」,但原文說它用起來「像 local function call」?
根據原文,gRPC「據說比 JSON 快 5 倍」的原因是什麼?
🛰️
下一站:跟著一次呼叫走完全程

三樣配料都認識了,接下來把它們串起來——原文那張圖的 Step 1 到 Step 14,一個 REST 請求怎麼變成二進位、飛過網路、再變回結果。往下捲,按「下一步」跟著封包走。

02

跟著一次呼叫走完全程:gRPC 的資料流

一個 REST 請求怎麼變成二進位、飛過網路、被另一台伺服器執行,再原路變回結果——原文 Step 1 到 14,這裡走一遍給你看

先認識這趟旅程的三個角色

原文的資料流圖裡有幾個固定角色。先把它們認清楚,等下看動畫才不會迷路:

🖥️
client(客戶端)

發起請求的那一方,例如使用者的瀏覽器或 App。它送出的是一般的 REST 呼叫,請求主體通常是 JSON。

🧾
order service(訂單服務,gRPC client)

收下 client 的 REST 呼叫。在這趟旅程裡,它同時扮演 gRPC client:負責把請求轉換、編碼成二進位,再對付款服務發出 gRPC 呼叫。

💳
payment service(付款服務,gRPC server)

另一台伺服器上的服務,扮演 gRPC server:從網路收下封包、解碼、真正執行伺服器端的應用程式邏輯,再把結果原路送回。

🔀
同一個服務,兩種身分

留意一個容易搞混的點:order service 對使用者來說是伺服器(它收 REST 請求),但對 payment service 來說它是客戶端(它發 gRPC 呼叫)。同一個服務在不同關係裡扮演不同角色,這在微服務裡非常常見。中間那條網路,我們用一個 HTTP/2 傳輸層節點來代表。

招牌互動:按「下一步」,跟著封包走一趟

下面把原文的 Step 1–14 壓縮成 8 個關鍵步驟,順序完全忠於原文:從 client 發 REST 請求,到訂單服務編碼、經 HTTP/2 送出、付款服務執行、結果原路解碼送回。按「下一步」,留意兩件事:編碼/解碼總是成對出現(去程編、回程解),以及封包過網路那一步走的是 HTTP/2。

🖥️
client
🧾
order service
🌐
HTTP/2 網路
💳
payment service
按「下一步」開始這趟旅程
🔁
整趟旅程的對稱性

看出那條對稱線了嗎?去程:order service 編碼 → 過網路 → payment service 解碼、執行。回程:payment service 把結果編碼 → 過同一條網路 → order service 解碼、交還 client。編碼與解碼永遠成對,就像寄信要封信封、收信要拆信封。這正是 gRPC 把「網路那攤事」藏起來的具體樣貌。

動手對對看:每一步是誰做的?

把下面四個動作,拖到負責它的角色上。想不起來就往上滑,再看一次動畫。

發出 REST 呼叫,請求主體是 JSON
收下 REST 呼叫、轉換並編碼成二進位 stub,發出 gRPC 呼叫
承載封包飛過網路,走的是 HTTP/2
收封包、解碼,invoke 伺服器端應用程式
client(客戶端)
拖到這裡
order service(gRPC client)
拖到這裡
HTTP/2 傳輸層
拖到這裡
payment service(gRPC server)
拖到這裡

小試身手

整趟資料流都跟上了。來兩題收尾:

封包從 order service 飛到 payment service,過網路那一步走的是什麼協定?
payment service 從網路收下封包後,第一件要做的事是什麼?
🙋
Over to you(原文留給你的思考題)

原文結尾丟出兩個問題:你在自己的專案裡用過 gRPC 嗎?它有哪些限制?想一想——例如它傳的是二進位,人不容易直接讀來除錯;瀏覽器也不能原生直接發 gRPC 呼叫(常需要 gRPC-Web 這類橋接)。這些取捨,正是你決定「這裡該用 gRPC 還是普通 REST」時要權衡的。