---
title: "如何在零停機下遷移 RPC 供應商"
description: "遷移 RPC 供應商只是換端點，不是重建。本文說明直接替換相容性涵蓋哪些範圍、該先檢查什麼，以及如何在不停機的情況下切換。"
---

# 如何在零停機下遷移 RPC 供應商

<ImageBlock
  src="https://media.alchemy.com/blog/migrate-between-rpc-providers-zero-downtime-16x9-20260821.png"
  alt="在 RPC 供應商之間遷移，零停機時間"
  width={1920}
  height={1080}
  priority
/>

團隊會拖延更換 RPC 供應商，因為感覺上像是要重建整個系統。但實際上多半只需要幾個小時的設定。每家主要供應商都採用相同的 JSON-RPC 標準，所以你的應用程式今天送出的請求，明天換到新供應商時仍然適用。遷移 RPC 供應商是端點的替換，不是重寫。

剩下的工作都在替換本身之外：找出所有端點 URL 藏身的地方、盤點那些無法直接搬過去的特定供應商呼叫、以及依序切換流量而不讓使用者察覺。

## 什麼是「即插即用」的端點相容性？

即插即用的端點相容性，是指兩個 RPC 供應商對於標準 JSON-RPC 方法能接受相同的請求，並回傳相同的回應。應用程式只要改變呼叫的端點 URL，就能切換供應商。方法名稱、參數、回應格式都維持不變，所以標準介面完全不需要修改程式碼。

這種相容性來自協定本身，而不是供應商之間的協議。`eth_call`、`eth_getLogs`、`eth_sendRawTransaction`，以及 `eth_*`、`net_*`、`web3_*` 系列的其他方法，都是由 [Ethereum JSON-RPC 規範](https://ethereum.org/en/developers/docs/apis/json-rpc/)所定義，任何正經的供應商都會按照規範實作。串流也是一樣的道理。透過 WebSocket 的 `eth_subscribe`，在[我們的訂閱端點](https://www.alchemy.com/docs/reference/subscription-api)上傳送的 newHeads、logs 和 newPendingTransactions 串流，和其他主要供應商上的是一樣的。

以下是我們的端點格式，與大多數其他供應商採用的格式對照：

<CodeSnippet
  language="text"
  code={`Alchemy:         https://eth-mainnet.g.alchemy.com/v2/YOUR_API_KEY
Other providers: https://your-endpoint-name.provider.example/YOUR_AUTH_TOKEN/`}
/>

兩者都是路徑中帶有密鑰的 URL。如果你的端點存在環境變數裡，遷移標準流量就只是改變這個變數的值。這也是為什麼「保留一個[備援 RPC 端點](https://www.alchemy.com/overviews/alternative-rpc-endpoint)」這項標準的可靠性建議，同時也是遷移保險。你為了提升可用性而加入的備援機制，正是你用來切換的機制。

標準 JSON-RPC 呼叫在新供應商上不需修改即可執行。真正需要處理的地方，是你的應用程式依賴特定供應商功能之處，而找出這些地方正是盤點要做的事。

## 遷移前應該盤點什麼？

供應商遷移中大多數意外都是切換之後才被發現，但每一個其實都能在切換前找出來。對一般規模的程式碼庫來說，盤點大約花一兩個小時。

**找出所有端點參照。** 端點 URL 累積的地方比任何人記得的都多。搜尋環境變數檔、Hardhat 和 Foundry 設定、Docker 映像檔、CI pipeline，以及前端建置檔案中，目前供應商的網域和任何寫死的 URL。漏掉的那一個，通常藏在某個好幾個月沒人打開過的排程工作或 CI pipeline 裡。

**盤點供應商前綴方法。** 大多數供應商都會提供帶有廠商前綴的便利方法（我們的是 `alchemy_`），這些方法無法跨平台搬移。Token 查詢對應到 [Data API](https://www.alchemy.com/docs/data) 的等效方法，例如 [alchemy_getTokenBalances](https://www.alchemy.com/docs/data/token-api/token-api-endpoints/alchemy-get-token-balances)，轉帳紀錄則對應到 [alchemy_getAssetTransfers](https://www.alchemy.com/docs/data/transfers-api/transfers-endpoints/alchemy-get-asset-transfers)。等效方法是存在的，但回應格式不同，所以每一個都要當成小規模的程式碼修改來處理，而不是單純找換字串。

**檢查你的驗證方式。** URL 路徑中的金鑰可以直接搬移。如果你用 `x-token` header 或 JWT 來驗證，這些控制項就需要在新供應商上重新建立。在我們這邊，網域和 IP 白名單設定在 [Alchemy 儀表板](https://dashboard.alchemy.com)中，只需要幾分鐘就能完成。

**依照新的計費模型重新估算流量成本。** 這是盤點項目中會影響帳單而不是程式碼的一項。許多供應商是以固定的每秒請求數來計費。我們則是以[運算單位](https://www.alchemy.com/docs/reference/compute-unit-costs)計費，像 `eth_blockNumber` 這種輕量呼叫的成本比 `eth_getLogs` 這種重量呼叫低，而[吞吐量](https://www.alchemy.com/docs/reference/throughput)是在滾動時間窗內的運算單位速率，而不是固定的請求數上限。這種差異影響是雙向的：以日誌為主的索引工作負載，消耗的額度會比請求數字所顯示的快，而輕量輪詢工作負載消耗的則會較少。大多數團隊會在切換前，用自己流量最高峰的一小時去對照[我們的定價](https://www.alchemy.com/pricing)，而不是用每月總量去猜測。

**檢查 trace 和 debug 方法的方案限制。** `debug_` 和 `trace_` 方法在大多數供應商上都依方案限制。在 Alchemy 上，這些方法在[按用量付費方案和企業方案](https://www.alchemy.com/pricing)上可用，但免費方案不行，所以如果你在免費端點上跑概念驗證，要預期 trace 呼叫在那裡會失敗，儘管其他一切都能正常運作。

以上這些項目都不會阻擋遷移，但加總起來會決定遷移的範圍。對大多數應用程式而言，盤點結束時會得到一份環境變數的簡短清單、一兩個方法對應，以及一個定價估算。

## 如何做到零停機切換？

零停機模式和團隊用於資料庫遷移的模式相同：新舊並行執行，分階段搬移流量，並在新路徑贏得信任之前，保持舊路徑暢通。

客戶端函式庫讓並行階段幾乎零成本。viem 的 [fallback transport](https://viem.sh/docs/clients/transports/fallback) 接受一份有序的端點清單，一個失敗就往清單下一個移動：

<CodeSnippet
  language="typescript"
  code={`import { createPublicClient, fallback, http } from "viem";
import { mainnet } from "viem/chains";
const client = createPublicClient({
  chain: mainnet,
  transport: fallback([
    http("https://eth-mainnet.g.alchemy.com/v2/YOUR_API_KEY"),
    http("https://your-endpoint-name.provider.example/YOUR_AUTH_TOKEN/"),
  ]),
});`}
/>

把新供應商放在第一位、舊供應商放在第二位，每個請求都會先試新端點，失敗再退回原本就能用的那個。切換期間最壞的情況，就是你現在的設定。ethers.js 在 [FallbackProvider](https://docs.ethers.org/v6/api/providers/fallback-provider/) 中提供相同的模式，還有一個法定人數（quorum）選項，會查詢多個供應商，並在它們達成一致時才接受結果，讓你在客戶端內部就能做到跨供應商的一致性檢查。

流量搬移的順序比搬移速度更重要，原則是：先讀後寫。讀取是無狀態的，也容易驗證，所以應該及早把讀取流量導向新端點，並比對回傳結果。在兩個供應商上都執行你最重的查詢，例如針對你合約最繁忙區塊範圍的 `eth_getLogs`，以及針對核心合約的 `eth_call`，然後比較回應結果。交易送出要最後搬移，等讀取都驗證無誤之後才進行，因為讀取失敗頂多重試，寫入失敗就是一張客服工單。

WebSocket 訂閱需要多一個步驟。訂閱綁定在建立它的連線上，所以不會自動容錯切換，而是會中斷，你必須重新建立。計畫在新端點上重新訂閱，並用 `eth_getLogs` 查詢重新連線期間經過的區塊，補上缺口，確保不漏掉任何事件。我們的 [WebSocket 最佳實務](https://www.alchemy.com/docs/reference/best-practices-for-using-websockets-in-web3)也建議把訂閱範圍盡量縮小，這樣重新訂閱和補資料的成本都會更低。

並行執行期間有兩件事值得放上儀表板。第一是區塊高度落後。兩個健康的供應商在任何時刻都可能停在稍微不同的鏈頭位置，所以應該針對新端點持續落後舊端點的情況發出警示，而不是針對瞬間的差異。第二是錯誤格式。速率限制的回應在不同供應商間並不相同。以 HTTP 來說，我們回傳帶有 [Retry-After header](https://www.alchemy.com/docs/reference/throughput) 的 429；以 WebSocket 來說，同樣的限制會以沒有 header 的 JSON-RPC 429 錯誤呈現。在讓新端點承載正式流量之前，先在你使用的兩種傳輸方式上測試你的重試邏輯。

大多數團隊會讓並行階段跑一兩天的正式流量，再把新端點設為預設。舊端點繼續設定為備援，直到其計費週期結束。整個過程中，回退隨時只要一個設定變更就能完成，這就是零停機在實務上的意義。事情仍然可能出錯，只是不需要影響到你的使用者。

## 如何確認新供應商運作正常？

你在並行階段所做的比對，就是你的基準線。切換之後，持續觀察你先前比對的數字：成功率、p95 延遲，以及區塊新鮮度。如果這次遷移值得做，至少其中一項應該會往有利的方向移動。

延遲的說法你也不必只憑信任接受。我們的[即時 RPC 基準測試](https://www.alchemy.com/benchmarks)比較我們與其他主要供應商在不同鏈和地區的表現，而[背後的方法論](https://www.alchemy.com/blog/how-we-benchmark-rpc-performance)是公開的，所以你可以在決定之前，從自己所在的地區重現這些數字。至於這些數字為何在負載下依然成立的更深入說明，我們的[邊緣代理重建](https://www.alchemy.com/blog/alchemy-edge-proxy)介紹了每個請求最先經過的路由層。

如果你還在比較供應商，而不是在驗證某一個，我們的[選擇節點供應商指南](https://www.alchemy.com/overviews/how-to-choose-a-blockchain-node-provider)和[企業級 RPC 評估指南](https://www.alchemy.com/blog/blockchain-rpc-infrastructure-evaluation-guide-for-enterprises)涵蓋了在談到遷移之前就該先問的問題。

遷移完成後，也要持續保留並行執行期間的檢查機制。用來驗證切換的回應比對和延遲儀表板，幾個月後同樣能標示出供應商的退化或過時資料，而且這些機制早已建置完成。

## 準備好更換 RPC 供應商了嗎？

不論你目前用的是哪家供應商，以上所有內容都直接適用。

在 [Alchemy 儀表板](https://dashboard.alchemy.com)建立一個免費端點，今天就讓你的 staging 環境指向它。不需要簽約、不需要業務電話、沒有最低使用量承諾。免費方案每月包含 [3000 萬運算單位](https://www.alchemy.com/pricing)，足以在真實正式流量上完整跑一遍並行階段的比較，而且同樣的端點替換方式適用於我們[支援的 100 多條鏈](https://www.alchemy.com/rpc)。
