跳至內容
0%

Webhooks、WebSockets 與 gRPC 比較

發布於 2026年5月19日閱讀時間 4 分鐘

比較 webhooks、WebSockets 與 gRPC 即時資料傳輸方式的封面圖

每個讀取區塊鏈資料的應用程式都會遇到同樣的架構問題:資料該如何送達你的系統?每隔幾秒輪詢一次 API,會浪費運算資源、錯過事件,還會增加延遲。改用推送資料的方式,就得選定一種傳遞模型。

即時資料傳遞主要由三種協定主導:webhooksWebSockets 和 gRPC。它們並不能互相替代。Webhooks 在事情發生時通知你的後端。WebSockets 將即時資料串流至瀏覽器。gRPC 則在後端服務之間以高吞吐量傳輸資料。選錯協定,代價會在之後才顯現:漏接的事件、浪費的運算資源,或是一場你原本沒打算進行的系統重新設計。

Webhooks、WebSockets 和 gRPC 是什麼?

這三者都能將資料從伺服器傳送到你的應用程式,而不需要輪詢。相似之處僅止於此。

webhook 顛覆了一般的 API 方向。你的程式不去呼叫伺服器,而是伺服器在關注的事情發生時,呼叫你註冊的 URL,並附上 JSON 資料。Webhooks 設定起來簡單;代價是你無法控制資料抵達的時機或格式。

WebSocket 是客戶端與伺服器之間持久的 TCP 連線。任一方都能在任何時間傳送小型二進位資料訊框,而不需要重新建立連線。這個協定一開始是 HTTP 請求,一旦雙方同意升級,就會轉換成原始 socket。

gRPC 是一種遠端程序呼叫(RPC)框架:讓一個服務能像呼叫本地函式一樣呼叫另一個服務中的函式的系統。它是 Google 內部 RPC 系統 Stubby 的公開後繼者,運行於 HTTP/2 之上,以 Protocol Buffers 序列化資料,並支援四種串流模式,包括完整的雙向串流。它是為了讓後端服務快速在機器之間傳輸結構化資料而打造的,內建重試機制、期限(deadline)傳播和型別化的合約。

Dimension
Webhooks
WebSockets
gRPC
協定
HTTP POST 回呼
持久 TCP(RFC 6455
方向
伺服器到接收方(單向)
雙向
雙向(4 種串流模式)
連線模型
無狀態(每個事件一個新請求)
有狀態(持久)
有狀態(持久、多工)
資料格式
JSON
JSON 或二進位
Protobuf(二進位)
每則訊息額外負擔
500-2,000 位元組(HTTP 標頭)
2-6 位元組
5 位元組訊框 + 壓縮標頭
瀏覽器支援
不適用(伺服器端)
原生支援(99% 以上)
需要 gRPC-Web proxy
傳遞保證
至少一次(含重試)
無內建保證
可設定的重試 + 期限
最適合場景
事件通知
即時瀏覽器 UI
服務對服務的資料管線

Webhooks 是如何運作的?

Webhooks 顛覆了 API 模型。不是你去呼叫伺服器,而是伺服器來呼叫你。你向提供者註冊一個 URL,告知哪些事件是你關注的,然後等待。事情發生時,提供者會將 JSON POST 至你的端點,並預期收到 2xx 回應。

javascript
Copied
app.post('/webhook', (req, res) => { const sig = req.headers['x-alchemy-signature']; if (!verify(sig, req.rawBody, SECRET)) return res.status(401).end(); queue.enqueue(req.body); res.status(200).end(); });

上面的程式碼片段是一個 webhook 處理常式:它驗證簽章、將 payload 排入佇列,然後回傳 200。上面這個簡易版本,也正是大多數正式環境 webhook 中斷事故的根源。真正將玩具等級的處理常式和正式環境等級的處理常式區分開來的,是三件事的處理方式:簽章驗證、重試行為、以及突發過載。

第一種失效模式是脆弱的簽章處理。提供者會用共享密鑰對每次傳遞進行 HMAC 簽章(Alchemy 使用 X-Alchemy-Signature,Stripe 使用 Stripe-Signature),而你的處理常式必須重新計算 HMAC,以固定時間比較的方式來避免計時攻擊,並拒絕任何時間戳記超過五分鐘的請求。呼叫 verify() 只是一行程式碼;但要正確地做到這件事,得花上好幾行。任何一個步驟被省略,你等於是在信任任何知道你端點 URL 的程序。

第二種失效模式是在重試機制下的非冪等(non-idempotent)處理。當傳遞失敗時(逾時、部分中斷、5xx 回應),提供者會以指數退避的方式重試(通常從一秒開始加倍、加上抖動、上限為一小時),持續數小時或數天,最終才會把 payload 送進死信佇列。Webhooks 保證至少一次傳遞,而非恰好一次(恰好一次在分散式系統中是不可能達成的),所以重複傳遞是常態。你的處理常式必須具備冪等性:處理同一個事件兩次,應該和只處理一次得到相同的結果。用去重儲存體追蹤事件 ID,遇到重複時回傳 200。

第三種失效模式是突發過載,這也是在規模擴大後最容易讓 webhook 系統崩潰的一種。單一鏈上事件就可能觸發數百萬次同時發生的傳遞。如果你的端點成為瓶頸,提供者的重試佇列就會變成攻擊你的 DoS 來源。

在區塊鏈基礎設施中,webhooks 是事件驅動工作流程的核心。我們的 Custom Webhooks 支援地址活動監控、NFT 轉移提醒,以及跨越 30 多條 EVM 鏈加上 Solana 的 GraphQL 過濾智能合約事件,全部以 HTTP POST 回呼的方式傳送到你的端點。

WebSockets 是如何運作的?

WebSocket 一開始是一個帶有 Upgrade: websocket 標頭的普通 HTTP 請求。伺服器回覆 HTTP 101(Switching Protocols),從那一刻起,這個連線就不再使用 HTTP。這個協商過程就是 WebSocket 交握(handshake)。之後留下的是一條原始 TCP socket,上面覆蓋了一層薄薄的訊框機制:每則訊息不需要標頭,也沒有請求—回應循環。

移除 HTTP 讓 WebSockets 每則訊息的成本大幅降低。每則 WebSocket 訊息只帶有 2-6 位元組的額外負擔(一個 FIN 位元、opcode,以及 payload 長度)。相比之下,HTTP 的每個請求都包含數百位元組的標頭。以每秒 100 則訊息計算,WebSocket 的額外負擔約為每秒 600 位元組,而等量的 HTTP 流量則是每秒 60,000 位元組。

javascript
Copied
const ws = new WebSocket('wss://eth-mainnet.g.alchemy.com/v2/KEY'); ws.send(JSON.stringify({ jsonrpc: '2.0', id: 1, method: 'eth_subscribe', params: ['newHeads'] })); ws.on('message', (data) => handleBlock(JSON.parse(data)));

WebSocket 連線是有狀態且長時間存在的。任一方都可以在任何時間傳送資料,不需要等待對方。伺服器會定期傳送 ping 訊框;客戶端則以 pong 訊框回應,證明連線仍然存活。少了這些心跳訊號,失效的連線(「殭屍連線」)會白白佔用伺服器資源,反向代理伺服器也會在閒置 30-120 秒後將連線關閉。

代價是:連線的生命週期由你自己負責管理,而這個生命週期裡涉及的細節比表面看起來更多。連線斷線時,客戶端必須重新連線,而且必須以指數退避方式重連(每次重試間隔逐漸拉長),否則數千個客戶端同時重連會壓垮伺服器。當你在負載平衡器後面運行多台 WebSocket 伺服器時,負載平衡器必須將特定客戶端的每次重連都導回同一台機器,因為只有那台機器持有該客戶端的訂閱狀態。這條路由規則有個名稱:session affinity(連線親和性)。而如果一則訊息源自某台伺服器,卻需要傳給連線在另一台伺服器上的客戶端,這些伺服器之間就必須跨節點共享狀態。WebSockets 提供的只是傳輸協定;建構在它之上的一切都得靠你自己完成。

對於區塊鏈應用程式而言,WebSockets 是即時事件訂閱的標準介面。Ethereum 的 eth_subscribe 端點 透過持久的 WebSocket 連線推送新的區塊標頭、日誌事件和待處理交易。我們的 Smart WebSockets 在基礎協定之上,加入了過濾訂閱與自動重連功能。

將即時資料串流至瀏覽器,正是 WebSockets 被設計來解決的問題。在 WebSockets 出現之前,可用的替代方案(長輪詢、伺服器發送事件)不是每則訊息都要付出完整的 HTTP 額外負擔,就是只能單向運作。WebSockets 在原本原始 TCP socket 通常無法存在的地方——瀏覽器——提供了持久、低額外負擔、雙向的連線。

這種清晰的定位,同時也是它的侷限。當消費端不是瀏覽器、資料是結構化的、流量很大,而你又需要 WebSockets 從未承諾過的東西:型別化的架構定義、多工串流、期限傳播、背壓機制——這時 WebSockets 就會顯得力不從心。而這正是 gRPC 被設計來解決的問題。

gRPC 是如何運作的?

gRPC 從設計空間的另一端出發。Webhooks 是 HTTP 回呼、WebSockets 是 TCP 之上的一層薄薄訊框機制,而 gRPC 則是一個以型別化合約為核心的完整 RPC 框架。在撰寫任何業務邏輯之前,你要先寫一個 .proto 檔案,定義服務以及它所收發的訊息。protobuf 編譯器會將這個檔案轉換成你所用語言的客戶端與伺服器端產生碼(稱為 stub),因此在程式碼中呼叫遠端方法,看起來就像呼叫本地函式一樣。

protobuf
Copied
service Geyser { rpc Subscribe(stream SubscribeRequest) returns (stream SubscribeUpdate); }

傳輸層是 HTTP/2,搭配 Protocol Buffers 做序列化。兩者結合,讓 gRPC 相較於典型的 REST + HTTP/1.1 + JSON 技術堆疊,具備三項優勢:

  • 多工機制消除了 head-of-line blocking(隊頭阻塞)問題——這是 HTTP/1.1 的問題,指單一緩慢的回應會拖住同一連線上後續的每個請求。在 gRPC 中,每次呼叫都以獨立的 HTTP/2 串流運行,共享同一條 TCP 連線。Square 就是眾多將內部服務對服務流量遷移到 gRPC 以降低連線額外負擔的工程團隊之一。
  • 標頭壓縮(HPACK)以精簡的參照取代重複的標頭。在 RPC 流量中,同樣的方法、內容類型和驗證標頭會在每次呼叫中重複出現,這項機制將標頭額外負擔降低了 85-90%
  • Protocol Buffers 將訊息序列化為緊湊的二進位格式,而非文字格式。在未壓縮的環境中,payload 比 JSON 小 34%,反序列化速度則最多快上 6 倍,視所用語言而定。代價是:二進位 payload 無法直接以人眼閱讀,因此需要 grpcurl 或 Postman 之類的工具來檢視流量。

gRPC 支援四種串流模式。Unary(一個請求、一個回應)的運作方式類似標準 API 呼叫。Server streaming(一個請求、多個回應)適合資訊流與資料推送。Client streaming(多個請求、一個回應)用於處理批次上傳。Bidirectional streaming(雙方各自獨立傳送)則為即時、有狀態的互動提供支援。

gRPC 並不是一個通用協定。它是為了在你完全掌控兩端的機器之間,以高速率傳輸結構化資料的後端服務而窄向優化的,而正是這個聚焦的利基場景,讓撰寫架構定義與執行程式碼產生所付出的前期成本能夠得到回報。讓 gRPC 佔據這個位置的,不只是二進位編碼,更是內建於協定中的正式環境級基礎機制。期限傳播 將每個逾時設定轉換成一個絕對的時間點,並貫穿整個呼叫鏈。如果服務 A 設定了 5 秒的期限並呼叫服務 B,而服務 B 又呼叫服務 C,每一跳都能確切知道還剩多少時間。期限一到,所有下游工作都會取消並釋放資源。流量控制 繼承自 HTTP/2:當消費端速度跟不上時,傳送端會自動放慢速度來配合。這是內建的背壓機制,而 webhooks 和 WebSockets 都沒有原生提供這種功能。

Solana 上,gRPC 支撐著目前可用的最高效能資料串流。Yellowstone gRPC 插件(Geyser)直接載入驗證節點的記憶體空間,在帳戶與交易更新寫入磁碟之前就先擷取它們,將其序列化為 protobuf,再透過持久的 HTTP/2 串流推送出去。

這三種協定在效能上如何比較?

吞吐量與延遲基準測試為服務對服務通訊劃出了清晰的界線。二進位 protobuf 編碼加上 HTTP/2 多工,讓 gRPC 相較於 REST over HTTP/1.1 具有可衡量的更高吞吐量與更低延遲,在 payload 小且並行呼叫數量多的工作負載中尤其明顯。

WebSockets 則在另一項比拚中勝出:瀏覽器與伺服器之間串流的每則訊息額外負擔最低。初次交握完成後,每則訊息只帶有 2-6 位元組的訊框額外負擔,且瀏覽器原生的 WebSocket API 就能處理連線,不需要 proxy 或建置工具。

Webhooks 並不是為了效能而設計的。每次傳遞都是一個獨立的 HTTP 請求,帶有完整的連線建立額外負擔。它們解決的是另一種問題:可靠的、非同步的事件通知,在這種場景中,簡單性和相容性比吞吐量更重要。

Metric
Webhooks
WebSockets
gRPC
每則訊息延遲
最高(完整 HTTP 往返)
低(2-6 位元組訊框)
最低(二進位 + 多工)
吞吐量上限
受限於 HTTP 額外負擔
單一串流時高
最高(多工串流)
序列化成本
僅 JSON
JSON 或二進位
連線建立
每個事件一次(或重用連線)
一次,之後持久
一次,之後持久 + 多工
背壓機制
無(由接收方吸收或失敗)
無內建機制
內建(HTTP/2 流量控制)

區塊鏈相關的具體數字也印證了這個模式。Solana 的 Yellowstone gRPC 串流資料的 slot 延遲約為 5 毫秒;原生 WebSockets 傳遞延遲約為 10 毫秒;RPC 輪詢則落後至約 150 毫秒。協定複雜度每提升一個層級,都能換來可衡量的速度提升。

每種協定在什麼情況下會出問題?

Webhooks 在高頻事件下會出現問題。在每秒數百次傳遞的規模下,每次回呼的 HTTP 額外負擔就會成為瓶頸。突發事件會造成驚群效應(thundering-herd)問題:一個重大的鏈上事件會同時觸發數百萬次 webhook 傳遞,讓提供者的重試佇列和消費端端點都不堪負荷。Webhooks 也是嚴格單向的。任何需要雙向通訊的使用案例都需要另一種協定。正如一位打造過 webhooks 基礎設施的工程師所描述的:「webhooks 運行起來很痛苦。」

WebSockets 在規模擴大時會遇到問題。每條連線都佔用伺服器資源(閒置時 2-10 KB,活躍時更多)。經過調校的伺服器可以處理超過 50 萬條閒置連線,但真正的瓶頸在於連線流動:TLS 交握每個 CPU 核心每秒只能處理 1,000-3,000 次。當伺服器重啟時,所有已連線的客戶端會同時重連,形成重連風暴,甚至可能演變成完全中斷。在 Solana 上,標準 WebSocket 實作「在負載下變得不可靠」,效能下降且經常斷線,這也促使 Solana 團隊轉向 gRPC。

gRPC 在瀏覽器端會遇到問題。瀏覽器無法原生使用 gRPC。gRPC-Web 協定 透過 proxy(通常是 Envoy)來彌合這道差距,但在過程中會失去 client streaming 和 bidirectional streaming 的能力。二進位 protobuf payload 無法用 curl 或瀏覽器開發者工具檢視,這讓 gRPC 不太適合注重開發者體驗的公開 API。protobuf 工具鏈(架構定義、程式碼產生、建置整合)也為簡單的整合增加了不小的建置成本。

該如何在 webhooks、WebSockets 和 gRPC 之間做選擇?

先從你的使用案例所需要的通訊模式著手判斷。

Webhooks 是預設選項。如果你的後端只需要在單一事件發生時得知(交易確認、NFT 轉移、付款完成),且事件頻率維持在每秒數百次以下,webhooks 就是成本最低的整合方式,能相容於任何語言、任何框架、任何防火牆。不需要持久連線、不需要串流基礎設施、也不需要客戶端 SDK。

當事件頻率上升,或你需要雙向的資料流動時,就輪到 WebSockets 出場。想想即時價格報價器、訂單簿更新、mempool 監控、協作式儀表板——任何情境只要持久連線到瀏覽器能讓你免於不斷敲打 API,就適合用 WebSockets。原生瀏覽器支援、不需要 proxy,訊框額外負擔以位元組計算。

當你需要後端服務之間的最大吞吐量時,選擇 gRPC。Indexer 資料管線、驗證節點資料串流、微服務對微服務的通訊,以及任何你能掌控連線兩端的工作負載,都能從二進位序列化、多工串流、型別化合約和內建背壓機制中受益。代價在於工具鏈:protobuf 架構定義、程式碼產生、不支援原生瀏覽器。當效能與可靠性的重要性超過建置複雜度時,這樣的投入是值得的。

當架構需要時,可以將它們組合使用。許多正式環境系統會同時使用這三種協定:gRPC 將資料從驗證節點串流到 indexer,WebSockets 將處理後的資料推送到瀏覽器儀表板,而 webhooks 則將離散事件通知外部系統。沒有理由非得全押在單一協定上不可。

Use case
Recommended protocol
Why
交易確認提醒
Webhooks
離散事件、簡單整合、至少一次傳遞
交易 UI 中的即時價格資訊流
WebSockets
持續傳送資料到瀏覽器、低延遲、雙向
Solana 驗證節點資料管線
gRPC
最大吞吐量、二進位序列化、背壓機制
Ethereum 新區塊訂閱
WebSockets
標準 eth_subscribe 介面、與瀏覽器相容
後端微服務通訊
gRPC
型別化合約、多工、期限傳播
第三方整合回呼
Webhooks
通用 HTTP 相容性、無需持久連線

在 Alchemy 上打造即時區塊鏈資料應用

我們在超過 100 條鏈上支援這三種協定。

我們的 Custom Webhooks 以 HTTP POST 回呼的方式傳遞交易確認、地址活動和 NFT 事件,並附帶 HMAC 簽章驗證與自動重試機制。GraphQL 過濾器讓你能精準訂閱應用程式所需的合約事件。

Smart WebSockets 提供經過過濾的 eth_subscribe 串流,並具備自動重連功能,為即時前端應用程式降低延遲。

對於處理大量資料的 Solana 團隊,我們的 Yellowstone gRPC streaming 能直接從驗證節點記憶體傳遞帳戶更新與交易資料,延遲低於 10 毫秒。

這三項服務都在我們的免費方案中提供。無需合約、無需候補名單。立即註冊,幾分鐘內就能開始串流資料。

常見問題

Webhooks、WebSockets 和 gRPC 之間的主要差異是什麼?

Webhooks 是用於伺服器對伺服器事件通知的單向 HTTP 回呼;WebSockets 提供客戶端與伺服器之間持久、雙向的連線;gRPC 則是建構在 HTTP/2 之上的 RPC 框架,專為具有型別化合約的高吞吐量服務對服務通訊而設計。

什麼時候該用 webhooks 而不是 WebSockets 或 gRPC?

當你需要離散事件通知(例如交易確認或 NFT 轉移),事件頻率在每秒數百次以下,且不需要持久連線時,就該使用 webhooks。它們是最簡單的整合方式,不需要專用的客戶端 SDK 或基礎設施。

什麼時候 WebSockets 是更好的選擇?

WebSockets 最適合用於持續、即時地將資料串流至瀏覽器客戶端,例如即時價格報價器、訂單簿更新或儀表板。它們提供原生瀏覽器支援,初次交握後每則訊息的額外負擔很低(2-6 位元組)。

gRPC 是為了解決什麼問題而設計的?

gRPC 是為了讓後端服務以高速率傳輸結構化資料而優化的,例如 indexer 資料管線或驗證節點資料串流。它提供二進位序列化、多工串流、透過 Protocol Buffers 實現的型別化合約、內建背壓機制以及期限傳播。

我能否在同一個系統中同時使用 webhooks、WebSockets 和 gRPC?

可以,許多正式環境系統會同時結合這三者:gRPC 用於後端服務對服務通訊,WebSockets 用於即時瀏覽器更新,webhooks 則用於通知外部系統離散事件。每種協定解決的是不同的架構層面。

這些協定之間的效能差異是什麼?

gRPC 透過二進位編碼與 HTTP/2 多工,提供最低的延遲與最高的吞吐量;WebSockets 為瀏覽器串流提供低額外負擔(每則訊息 2-6 位元組);webhooks 由於完整的 HTTP 往返額外負擔,每則訊息的成本最高,但更重視簡單性而非效能。

每種協定的主要缺點是什麼?

Webhooks 在高頻事件與突發流量下容易出問題;WebSockets 在規模擴大時面臨連線流動與驚群式重連風暴的挑戰;gRPC 需要建置 protobuf 工具鏈、不支援原生瀏覽器,且需要 proxy(gRPC-Web)才能供 Web 客戶端使用。

Alchemy 如何為區塊鏈應用程式支援這些協定?

Alchemy 提供 Custom Webhooks,可在 100 多條鏈上進行事件通知;提供 Smart WebSockets,實現具備自動重連功能的過濾 eth_subscribe 串流;並在 Solana 上提供 Yellowstone gRPC streaming,直接從驗證節點記憶體傳遞帳戶更新,延遲低於 10 毫秒。

Background gradient

打造區塊鏈魔法

Alchemy 結合最強大的 Web3 開發者產品與工具,並提供資源、社群與卓越的支援。