---
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がどこに隠れているかを洗い出すこと、そのまま移行できない一部のプロバイダ固有の呼び出しをマッピングすること、そしてユーザーに気づかれない順序でトラフィックを切り替えることだ。

## ドロップイン互換なエンドポイントとは何を意味するか

ドロップイン互換なエンドポイントとは、2つの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呼び出しは、変更なしに新しいプロバイダ上で動作する。作業が発生するのは、アプリがプロバイダ固有の何かに依存している箇所であり、そうした箇所を洗い出すためにあるのが監査だ。

## 移行前に何を監査すべきか

プロバイダ移行におけるトラブルの多くは切り替え後に発覚するが、そのすべては事前に見つけられたはずのものだ。一般的なコードベースであれば、監査には1〜2時間かかる。

**すべてのエンドポイント参照を見つける。** エンドポイントURLは、想像以上に多くの場所に散らばっている。環境変数ファイル、Hardhat・Foundryの設定、Dockerイメージ、CIパイプライン、フロントエンドのビルドについて、現在のプロバイダのドメインやハードコードされたURLを検索する。見落とされがちな参照は、たいてい何ヶ月も開かれていないcronジョブやCIパイプラインの中にある。

**プロバイダ固有プレフィックス付きのメソッドをマッピングする。** ほとんどのプロバイダは、ベンダー固有のプレフィックス付きの便利なメソッドを提供しており(当社の場合は`alchemy_`)、これらはプラットフォーム間で持ち越せない。トークン照会は[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`ヘッダーや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)はリクエスト数の固定枠ではなく、一定期間のコンピュートユニットレートとして扱われる。この違いは両方向に影響する。ログを多用するインデックス処理のワークロードは、リクエスト数から想像するより早く予算を消費する一方、軽いポーリング処理のワークロードはより少なく済む。多くのチームは、月間合計から推測するのではなく、実際のトラフィックが最も多い1時間分を切り替え前に[当社の料金体系](https://www.alchemy.com/pricing)に照らして試算している。

**traceおよびdebugメソッドのプラン制限を確認する。** `debug_`と`trace_`のメソッドは、ほとんどのプロバイダでプランによる制限がある。Alchemyでは[従量課金プランおよびエンタープライズプラン](https://www.alchemy.com/pricing)で利用可能だが無料プランでは利用できないため、無料エンドポイントでPoCを動かしている場合、他の機能は動いてもtrace呼び出しは失敗すると考えておくべきだ。

これらの項目はどれも移行の妨げにはならないが、合わせることで移行の作業範囲が定まる。ほとんどのアプリでは、監査の結果は環境変数の短いリスト、1〜2件のメソッドマッピング、そして価格見積もりに落ち着く。

## ダウンタイムなしで切り替えるにはどうすればよいか

ゼロダウンタイムのパターンは、データベース移行でチームが使うものと同じだ。旧・新を並行稼働させ、トラフィックを段階的に移し、新しい経路が信頼を得るまで旧経路を温存しておく。

クライアントライブラリを使えば、並行稼働のフェーズはほぼコストなしで実現できる。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/"),
  ]),
});`}
/>

新しいプロバイダを先頭に、旧プロバイダを2番目に置けば、すべてのリクエストはまず新しいエンドポイントを試し、失敗した場合は既に動いていた方にフォールバックする。切り替え中の最悪ケースは、現状と変わらない状態になる。ethers.jsも[FallbackProvider](https://docs.ethers.org/v6/api/providers/fallback-provider/)で同様のパターンを提供しており、複数のプロバイダに問い合わせて一致した結果を採用するクォーラムオプションもあるため、クライアント内部でプロバイダ間の結果一致チェックが行える。

トラフィックを移す速度よりも、移す順序の方が重要であり、その原則は「読み取りを先に、書き込みを最後に」だ。読み取りはステートレスで検証しやすいため、早い段階で読み取りトラフィックを新しいエンドポイントに向け、返ってくる結果を突き合わせる。コントラクトのブロック範囲が最も多い`eth_getLogs`や、コアコントラクトに対する`eth_call`といった負荷の高いクエリを両方のプロバイダで実行し、レスポンスを比較する。トランザクション送信は、読み取りの検証が済んでから最後に移す。読み取りの失敗はリトライで済むが、書き込みの失敗はサポートチケットになるからだ。

WebSocketのサブスクリプションには、もう一段階作業が必要になる。サブスクリプションは、それを作成した接続に紐づいているため、フェイルオーバーでは対応できない。接続が切れたら、サブスクリプションを作り直すことになる。新しいエンドポイントで再登録し、再接続の間に経過したブロックを`eth_getLogs`クエリでバックフィルする計画を立て、イベントが抜け落ちないようにする。当社の[WebSocketベストプラクティス](https://www.alchemy.com/docs/reference/best-practices-for-using-websockets-in-web3)でも、サブスクリプションの範囲を狭く保つことを推奨しており、これにより再登録もバックフィルも軽くなる。

並行稼働の期間中は、2つの項目をダッシュボードで監視する価値がある。1つはブロック高の遅延だ。健全な2つのプロバイダでも、ある瞬間にはチェーンの先端が多少ずれることがあるため、瞬間的な差ではなく、新しいエンドポイントが旧エンドポイントに継続的に遅れをとっていないかを監視対象とする。もう1つはエラーの形式だ。レート制限のレスポンスはプロバイダごとに異なる。HTTP経由では、当社は[Retry-Afterヘッダー](https://www.alchemy.com/docs/reference/throughput)付きの429を返すが、WebSocket経由では同じ制限がヘッダーなしのJSON-RPC 429エラーとして現れる。本番トラフィックを流す前に、使用している両方のトランスポートで、新しいエンドポイントに対してリトライロジックを試しておくこと。

多くのチームは、並行稼働フェーズに1〜2日分の本番トラフィックを与えたあと、新しいエンドポイントをデフォルトにする。旧エンドポイントは、課金期間が終わるまでフォールバックとして設定を残しておく。その間ずっと、ロールバックは設定変更1つで戻せる状態にあり、それが実際のゼロダウンタイムの意味だ。問題が起きること自体は避けられない。ただ、それがユーザーにまで届く必要はないというだけだ。

## 新しいプロバイダが問題なく機能しているかをどう確認するか

並行稼働フェーズで行った比較が、そのままベースラインになる。切り替え後も、切り替え前に突き合わせていた数値、つまり成功率、p95レイテンシ、ブロックの鮮度を監視し続ける。移行に意味があったのなら、少なくともそのうちの1つは良い方向に動くはずだ。

レイテンシに関する主張も、鵜呑みにする必要はない。当社の[ライブ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)で無料のエンドポイントを作成し、今日からステージング環境をそこに向けてみてほしい。契約も、営業への連絡も、最低利用条件も必要ない。無料プランには[月間3,000万コンピュートユニット](https://www.alchemy.com/pricing)が含まれており、実際の本番トラフィックで並行稼働フェーズの比較を一通り行うには十分な量だ。同じエンドポイントの差し替えは、[当社が対応する100以上のチェーン](https://www.alchemy.com/rpc)すべてで機能する。
