---
title: "如何針對你的工作流程對 RPC 提供方做基準測試"
description: "對 RPC 提供方做基準測試時，分別衡量負載下的延遲、區塊落後和數據一致性，測試你的應用程式實際呼叫的方法，並從它運行的地方發起。"
---

# 如何針對你的工作流程對 RPC 提供方做基準測試

<ImageBlock
  src="https://media.alchemy.com/blog/how-to-benchmark-rpc-providers-hero-v3.jpg"
  alt="以你的工作負載對提供方做基準測試"
  width={1024}
  height={480}
  priority
/>

選擇 RPC 提供方，應該依據專屬於你的工作負載的基準測試。我們持續對各家提供方做基準測試，包括我們自己，也看過許多團隊做同樣的事。送出請求是容易的部分。困難的是決定要衡量什麼，然後建構一個你真的願意拿來做決定的測試。

所以我們把方法論寫了下來，並打造了執行它的 Alchemy rpcbench：一個單一執行檔，從你自己的機器上，針對你的應用程式實際呼叫的方法，對任意一組 RPC 提供方做基準測試。方法論本身也適用於你手上已有的任何工具。

值得衡量的有三件事：負載下的延遲、區塊落後和數據一致性。每一項會出問題的地方都在系統的不同部分，而一家提供方可能在某一項表現強、在另一項落後，所以綜合分數會掩蓋對你真正重要的那一項。衡量你的應用程式實際呼叫的內容，並從它運行的地方發起。

## 對 RPC 提供方做基準測試時，應該衡量什麼？

負載下的延遲、區塊落後和數據一致性，分別衡量、分別報告。

<EmbeddedTable
  table={{
    columns: [
      { key: "dimension", width: 160, title: "面向", dataType: "object" },
      { key: "what", width: 260, title: "衡量的內容", dataType: "object" },
      { key: "how", width: 360, title: "衡量方式", dataType: "object" },
    ],
    data: [
      {
        dimension: { title: "負載下的延遲", tooltip: "", icon: "" },
        what: {
          title: "請求量上升時，提供方回應請求的速度",
          tooltip: "",
          icon: "",
        },
        how: {
          title:
            "逐步跑過幾個接近正式環境的 RPS 測試。在每一級讀取 p95 和 p99，並同時看失敗率和 429 比率",
          tooltip: "",
          icon: "",
        },
        id: 0,
      },
      {
        dimension: { title: "區塊落後", tooltip: "", icon: "" },
        what: {
          title: "提供方交付新區塊的速度",
          tooltip: "",
          icon: "",
        },
        how: {
          title:
            "同時在每家提供方上訂閱 <code>newHeads</code>。記錄每個區塊由誰最先宣告，以及領先多少",
          tooltip: "",
          icon: "",
        },
        id: 1,
      },
      {
        dimension: { title: "數據一致性", tooltip: "", icon: "" },
        what: {
          title: "區塊在宣告的那一刻，其數據是否已可提供",
          tooltip: "",
          icon: "",
        },
        how: {
          title:
            "在每個新區塊頭出現時，請求該區塊、它的日誌、收據和交易。檢查它們是否一致",
          tooltip: "",
          icon: "",
        },
        id: 2,
      },
    ],
  }}
/>

數據一致性是大多數團隊從未測試過的一項。有些提供方用不同的後端服務不同的方法，而這些後端不一定同步推進，所以提供方可能已經宣告了新的區塊頭，同一個區塊的日誌卻回傳不完整。就像一間圖書館先更新了館藏目錄，書卻還沒上架：目錄說新書已到，書架上卻是空的。

## 這幾項應該先衡量哪一項？

從與你的應用程式如何使用數據相符的那一項開始。如果你根據新區塊採取行動，那就是區塊落後。如果你在區塊一出現時就讀取它的日誌或狀態，那就是數據一致性。否則就是負載下的延遲。我們看過 Valantis、Aave、RedStone 和 Struct 等團隊，各自執行衡量不同面向的基準測試。

<EmbeddedTable
  table={{
    columns: [
      {
        key: "building",
        width: 240,
        title: "如果你在建構",
        dataType: "object",
      },
      { key: "first", width: 260, title: "優先衡量", dataType: "object" },
      { key: "risk", width: 280, title: "風險所在", dataType: "object" },
    ],
    data: [
      {
        building: {
          title:
            'DEX 或鏈上報價引擎（例如 <a href="/case-studies/how-valantis-built-a-reliable-trading-experience-on-hyperliquid">Valantis</a>）',
          tooltip: "",
          icon: "",
        },
        first: {
          title:
            "區塊落後，然後是定價邏輯發出的 <code>eth_call</code> 的 <strong>p99</strong>",
          tooltip: "",
          icon: "",
        },
        risk: {
          title: "你依據一個已經過時的區塊定價，或者報價送達時價差已經關閉",
          tooltip: "",
          icon: "",
        },
        id: 0,
      },
      {
        building: {
          title:
            '具清算機制的借貸協議（例如 <a href="/case-studies/how-aave-runs-largest-lending-protocol-alchemy">Aave</a>）',
          tooltip: "",
          icon: "",
        },
        first: {
          title:
            "區塊落後和數據一致性，然後是健康因子與價格讀取的 <strong>p99</strong>",
          tooltip: "",
          icon: "",
        },
        risk: {
          title:
            "清算晚了一個區塊才觸發，或者在該區塊數據可提供之前就讀取了部位",
          tooltip: "",
          icon: "",
        },
        id: 1,
      },
      {
        building: {
          title:
            '預言機或事件驅動服務（例如 <a href="/case-studies/how-redstone-keeps-price-feeds-reliable-across-51-chains">RedStone</a>）',
          tooltip: "",
          icon: "",
        },
        first: {
          title:
            "區塊落後和數據一致性，然後是 <code>eth_getLogs</code> 和 <code>eth_call</code> 的 <strong>p99</strong>",
          tooltip: "",
          icon: "",
        },
        risk: {
          title: "因為日誌回傳不完整而錯過觸發條件",
          tooltip: "",
          icon: "",
        },
        id: 2,
      },
      {
        building: {
          title:
            '索引器或錢包後端（例如 <a href="/case-studies/how-struct-is-building-the-data-layer-for-onchain-finance">Struct</a>）',
          tooltip: "",
          icon: "",
        },
        first: {
          title: "尖峰速率下的 <strong>p95</strong>，並同時看失敗率和 429 比率",
          tooltip: "",
          icon: "",
        },
        risk: {
          title: "回補停滯，或者在使用者交易時餘額變得過時",
          tooltip: "",
          icon: "",
        },
        id: 3,
      },
    ],
  }}
/>

接著一次比較一個方法，因為平均較快的提供方，在你的應用程式最常呼叫的那一個方法上仍可能較慢。這個差距就是關鍵所在：價差關閉後才送達的報價不是慢的報價，而是錯失的成交。

## 如何執行一個值得信賴的 RPC 基準測試？

按固定排程送出請求來衡量延遲。直覺的設計是送出一個請求、等待回應、再送下一個，而這種做法會在提供方開始吃力時悄悄減少請求量。你的測試在本應維持穩定的時刻放慢了，所以你想找的變慢現象永遠不會出現在數據裡。改為按固定時鐘送出，並追蹤每次送出落後時鐘多少。當你自己的機器跟不上時，數字描述的就是你的機器。

### 設定測試

<EmbeddedTable
  table={{
    columns: [
      { key: "rule", width: 300, title: "規則", dataType: "object" },
      { key: "why", width: 480, title: "為什麼重要", dataType: "object" },
    ],
    data: [
      {
        rule: {
          title:
            "測試你的應用程式實際呼叫的方法，並對所有提供方使用相同的 payload",
          tooltip: "",
          icon: "",
        },
        why: {
          title:
            "基準測試只能比較你送出的內容。每個方法單獨以全速率執行，否則成本高的方法永遠無法累積出穩定的尾部數據",
          tooltip: "",
          icon: "",
        },
        id: 0,
      },
      {
        rule: {
          title: "使用接近正式環境的 RPS 速率",
          tooltip: "",
          icon: "",
        },
        why: {
          title:
            "在 50 RPS 下看起來相同的提供方，到了 300 可能拉開差距。也要注意頻寬，因為範圍很廣的 <code>eth_getLogs</code> 會塞滿你的連線，看起來就像效能下降",
          tooltip: "",
          icon: "",
        },
        id: 1,
      },
      {
        rule: { title: "定義什麼算成功", tooltip: "", icon: "" },
        why: {
          title:
            "延遲只計算成功的請求，所以快速失敗不會得分。衡量到最後一個位元組的時間。把 429 單獨歸為一類",
          tooltip: "",
          icon: "",
        },
        id: 2,
      },
    ],
  }}
/>

### 執行測試

<EmbeddedTable
  table={{
    columns: [
      { key: "rule", width: 300, title: "規則", dataType: "object" },
      { key: "why", width: 480, title: "為什麼重要", dataType: "object" },
    ],
    data: [
      {
        rule: {
          title: "以相同方式為每家提供方暖機",
          tooltip: "",
          icon: "",
        },
        why: {
          title:
            "在每個方法開始前，對每家提供方以全速率送出十秒並捨棄結果。以時間為準，絕不以請求數為準：在 500 RPS 下，10 個請求只有 20ms 的暖機",
          tooltip: "",
          icon: "",
        },
        id: 0,
      },
      {
        rule: {
          title: "守住排程，觀察你自己的機器",
          tooltip: "",
          icon: "",
        },
        why: {
          title:
            "如果在 1,000 個樣本中送出偏差的 p99 超過 5ms，就標記這次測試。到了那個程度，你衡量的是你的機器",
          tooltip: "",
          icon: "",
        },
        id: 1,
      },
      {
        rule: {
          title: "一次測試一家提供方",
          tooltip: "",
          icon: "",
        },
        why: {
          title:
            "同時執行時它們會爭搶你的頻寬，搶贏的一方看起來就比較快。讓每家輪流執行，並在每次測試之間調換順序",
          tooltip: "",
          icon: "",
        },
        id: 2,
      },
    ],
  }}
/>

區塊落後是例外。「誰最先宣告這個區塊」只有在同一時刻觀察每家提供方時才有意義，而且每個區塊只是一則小訊息，所以不會有人爭搶你的頻寬。

### 解讀結果

<EmbeddedTable
  table={{
    columns: [
      { key: "rule", width: 300, title: "規則", dataType: "object" },
      { key: "why", width: 480, title: "為什麼重要", dataType: "object" },
    ],
    data: [
      {
        rule: {
          title:
            "衡量兩家提供方在相同請求上的差距。如果這個差距有可能為零，就判為平手",
          tooltip: "",
          icon: "",
        },
        why: {
          title:
            "落在彼此信賴區間內的提供方，你的數據無法將它們區分開來。配對樣本少於 100 個時，完全不要下結論",
          tooltip: "",
          icon: "",
        },
        id: 0,
      },
      {
        rule: {
          title: "執行兩次，並從你的系統運行的地方發起",
          tooltip: "",
          icon: "",
        },
        why: {
          title:
            "延遲取決於你和提供方之間的網路路徑。執行兩次可以看出效能在不同網路條件下的表現",
          tooltip: "",
          icon: "",
        },
        id: 1,
      },
    ],
  }}
/>

## 什麼是 Alchemy rpcbench？

Alchemy rpcbench 是一個單一執行檔，從你的機器上、使用你自己的金鑰，執行上述完整的方法論。它只會向你設定檔中的端點送出請求，產生的 HTML 報告也直接交給你。

我們打造它，是因為把方法論寫下來只是容易的那一半。上面每一條規則都要花好幾天才能正確實作，而且大多數做錯時根本看不出來，這對測量工具來說是最糟的組合。

預設值只是起點。`workload:` 區段可以換上你自己的參數和方法：

<CodeSnippet
  language="yaml"
  code={`workload:
  - method: eth_call
    params:
      - to: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"  # a contract on your quote path
        data: "0x18160ddd"                                 # and your calldata
      - "$anchor"                                          # the pinned block every provider is asked about`}
/>

速率級距、持續時間、逾時和區塊落後的觀察時段也同樣可以設定，而預檢會在任何負載離開你的機器之前，以請求數、時間和頻寬估算這次測試的成本。這個估算以 Alchemy 運算單位計價，所以請把它當作規模檢查來看。

每次測試都會寫出一個 JSON 檔、CSV 彙總數據，以及一個獨立的 HTML 儀表板。它不會交給你它無法背書的數字。樣本過少、提供方被限流，或機器跟不上，都會在最上方被標示出來。

通過檢查的測試會依序給你四樣東西：

<EmbeddedTable
  table={{
    columns: [
      { key: "get", width: 240, title: "你會得到", dataType: "object" },
      { key: "tells", width: 540, title: "它告訴你什麼", dataType: "object" },
    ],
    data: [
      {
        get: { title: "有效性判定", tooltip: "", icon: "" },
        tells: {
          title: "這次測試是否值得引用。先看這一項，再看其他內容",
          tooltip: "",
          icon: "",
        },
        id: 0,
      },
      {
        get: { title: "比較結果", tooltip: "", icon: "" },
        tells: {
          title: "只列出足以超越雜訊的差距。區間重疊的會判為平手",
          tooltip: "",
          icon: "",
        },
        id: 1,
      },
      {
        get: { title: "各方法延遲", tooltip: "", icon: "" },
        tells: {
          title:
            "每個速率級距的 p50、p90、p95 和 p99，並同時列出成功率、失敗率和 429 比率",
          tooltip: "",
          icon: "",
        },
        id: 2,
      },
      {
        get: { title: "區塊落後與一致性", tooltip: "", icon: "" },
        tells: {
          title:
            "每個區塊由誰最先宣告、其他提供方落後多少、遺漏的區塊，以及每個區塊頭的數據是否可提供",
          tooltip: "",
          icon: "",
        },
        id: 3,
      },
    ],
  }}
/>

## 這套方法論無法告訴你的事

- 一個區域的結果無法代表另一個區域。如果你的系統運行在別處，就從那裡執行。
- 區塊落後是相對於你測試過的最快提供方，而不是相對於真正的鏈頂端。
- 方法一次執行一個，所以一次測試永遠不是你線上流量組合的重播。
- 一次測試只是一個數據點。我們強烈建議執行多次，以取得可靠的效能訊號，因為許多因素都可能影響讀數，包括全鏈範圍的問題。
- Alchemy rpcbench 工具僅適用於 EVM 網路，每次測試支援一個網路。

## 如何取得 Alchemy rpcbench？

Alchemy rpcbench 目前處於私人 alpha 階段。[填寫這份表單](/rpcbench-access)申請使用權限！

如果你更想用手上已有的工具自己建構，上面的方法論就是全部內容。無論哪種方式我們都樂見，只要你最終據以行動的數字是你自己產生的。

## 常見問題

### 我應該如何比較 RPC 提供方？

從你的系統運行的區域，針對它實際呼叫的方法，對每家提供方執行相同的工作負載。按固定排程送出、一次測試一家提供方，並固定一個區塊，讓每家回答同一個問題。逐個方法解讀結果，每個延遲數字旁都列出失敗數和速率限制數，然後在不同時間重複一次。如果你不想自己建構，可以[與我們聯繫](/rpcbench-access)取得 Alchemy rpcbench 的使用權限。

### RPC 延遲、區塊落後和數據一致性有什麼不同？

延遲是提供方回應你送出的請求所需的時間。區塊落後是它告訴你新區塊已存在所需的時間。數據一致性是在它宣告的那一刻，該區塊的日誌、收據和交易是否已可提供。一家提供方可能三項都強，也可能某一項強、另一項落後，這就是它們應該分欄呈現的原因。

### 我能相信提供方打造的基準測試工具所產生的結果嗎？

可以，而且你不必只聽我們的說法。Alchemy rpcbench 中沒有任何程式路徑會依據它所連線的提供方而分支，所以針對特定提供方的逾時或重試設定無處可藏。用 README 中的稽核提示，讓任何程式開發代理檢查你複製下來的程式碼，它就會替你確認。這個工具在你的機器上、使用你的金鑰執行，結果永遠不會離開你的輸出資料夾。

### 我應該根據單一的整體效能分數來選擇 RPC 提供方嗎？

不應該。綜合分數替你決定了權重，而正確的權重取決於你的應用程式。回補歷史數據的索引器，和搶在區塊之前完成交易的套利機器人，對提供方的需求幾乎沒有共通之處。看與你所建構的產品相符的那個面向，然後逐個方法解讀。

### 應該從哪裡執行 RPC 基準測試？

從你的應用程式運行的區域。RPC 延遲在很大程度上取決於客戶端和提供方之間的網路路徑，所以從筆電或從你沒有部署的雲端區域執行的基準測試，衡量的是你的正式環境流量永遠不會經過的路徑。

### 執行一次 RPC 基準測試需要多久？

執行時間取決於你如何設定測試，但預設設定大約需要兩小時。你可以在 10 分鐘內完成設定並開始執行測試。Alchemy rpcbench 隨附的設定在 Ethereum 上對每家提供方送出 280,000 個請求，涵蓋七個方法和三個速率級距，大約需要 48 分鐘，區塊落後的觀察時段再加上一小時。提供方輪流執行，所以延遲階段的時間會隨你測試的家數增加。請預留一個下午，因為信心需要樣本來支撐。

### 對 RPC 提供方做基準測試需要 WebSocket 端點嗎？

衡量延遲不需要。衡量區塊落後和數據一致性則需要，因為兩者都依賴 `eth_subscribe` 和訂閱 `newHeads`。衡量區塊落後也至少需要兩家提供方，因為它衡量的是誰最先宣告每個區塊。

### 我可以測試哪些 RPC 提供方？

任何在你所測試的鏈上具有 EVM JSON-RPC 端點的提供方。URL 和金鑰由你提供，方法論和工具都不依賴提供方是誰。

### Alchemy 是否公布自己的 RPC 基準測試？

是的。我們的[基準測試頁面](/benchmarks)持續公布提供方之間的比較，你現在就可以查看。Alchemy rpcbench 則是讓你針對自己應用程式的工作負載、從它運行的區域，產生你自己的基準測試結果。
