跳至内容
0%

如何零停机迁移 RPC 提供商

作者:Uttam Singh

最后更新:2026年7月14日1 分钟阅读
在 RPC 提供商之间迁移,零停机

团队往往会推迟切换 RPC 提供商,因为这感觉像是一次重构。但多数情况下,这只是几个小时的配置工作。每个主流提供商都遵循相同的 JSON-RPC 标准,你的应用今天发出的请求,就是新提供商明天所期望的请求。迁移 RPC 提供商是换端点,不是重写代码。

剩下的工作都围绕这次替换展开,而不在替换本身之内:找出所有隐藏端点 URL 的地方,梳理那些少数不能直接迁移的提供商专属调用,并按用户无感知的顺序切换流量。

什么是即插即用的端点兼容性?

即插即用的端点兼容性是指两个 RPC 提供商对标准 JSON-RPC 方法接受相同的请求并返回相同的响应。应用只需更改调用的端点 URL 即可切换提供商。方法名、参数和响应结构保持不变,因此标准接口部分完全不需要改代码。

这种兼容性来自协议本身,而非提供商之间的约定。eth_call、eth_getLogs、eth_sendRawTransaction 以及 eth_*、net_*、web3_* 系列方法都由 Ethereum JSON-RPC 规范定义,任何靠谱的提供商都会按规范实现它们。流式接口同理。基于 WebSocket 的 eth_subscribe 在我们的订阅端点上携带的 newHeads、logs 和 newPendingTransactions 流,与在其他主流提供商上一样。

下面是我们的端点格式与多数其他提供商所用模式的对比:

text
Copied
Alchemy: https://eth-mainnet.g.alchemy.com/v2/YOUR_API_KEY Other providers: https://your-endpoint-name.provider.example/YOUR_AUTH_TOKEN/

两者都是路径中带密钥的 URL。如果你的端点存放在环境变量中,迁移标准流量就只是改这个变量的值。这也是为什么保留备用 RPC 端点这一常规可靠性建议,同时也充当了迁移保险。你为可用性添加的故障转移机制,正是切换时所用的同一套机制。

标准 JSON-RPC 调用在新提供商上可以直接运行。真正隐藏的工作在于你的应用依赖了哪些提供商专属的东西,而找出这些地方正是审计要做的事。

迁移前应该审计哪些内容?

提供商迁移中的大多数意外都是在切换之后才被发现的,而其中每一个原本都可以提前发现。对于一个典型的代码库,审计通常只需一两个小时。

找出所有端点引用。 端点 URL 会以超出大多数人记忆的方式散落在各处。搜索环境文件、Hardhat 和 Foundry 配置、Docker 镜像、CI 流水线以及前端构建中,是否存在当前提供商的域名或任何硬编码的 URL。最容易漏掉的引用,通常藏在某个几个月没人打开过的 cron 任务或 CI 流水线里。

梳理带提供商前缀的方法。 大多数提供商都会提供带厂商前缀的便捷方法(我们的前缀是 alchemy_),这些方法无法跨平台迁移。代币查询对应到 Data API 的等效方法,例如 alchemy_getTokenBalances,转账记录则对应 alchemy_getAssetTransfers。等效方法是存在的,但响应结构有所不同,因此应把每一个都当作小规模代码改动,而不是简单的查找替换。

检查你的鉴权方式。 URL 路径中的密钥可以直接迁移。但如果你使用 x-token 请求头或 JWT 鉴权,这些控制需要在新提供商上重新配置。就我们而言,域名和 IP 白名单设置在 Alchemy 控制台中,几分钟即可完成。

按新的计量模型重新估算流量成本。 这是审计项中唯一会影响账单而非代码的一项。许多提供商按固定的每秒请求数配额计量。我们按计算单元计量,像 eth_blockNumber 这样的轻量调用消耗的计算单元比 eth_getLogs 这样的重量调用少,而吞吐量是滚动窗口内的计算单元速率,而不是固定的请求数量。这种影响是双向的:日志密集型的索引负载消耗的配额,往往比其请求数所暗示的要快;而轻量轮询负载消耗的则更少。多数团队会在切换前,用我们的定价对最繁忙一小时的真实流量进行估算,而不是靠猜测月度总量。

检查 trace 和 debug 方法的套餐限制。 多数提供商对 debug_ 和 trace_ 方法按套餐分级限制。在 Alchemy,这些方法在按量付费和企业版套餐中可用,但免费套餐不支持,所以如果你在免费端点上跑概念验证,即使其他一切都正常,trace 调用也会失败,这一点要提前预料到。

以上任何一项都不会阻碍迁移,但合在一起就界定了迁移的范围。对多数应用来说,审计结束时得到的往往是一份简短的环境变量清单、一两个方法映射,以及一份定价估算。

如何做到零停机切换?

零停机的做法与团队用于数据库迁移的模式相同:新旧并行运行,分阶段迁移流量,并在新路径赢得信任之前,让旧路径保持可用。

客户端库让并行阶段几乎不费力气。viem 的fallback transport接受一个有序的端点列表,当某个端点失败时会转向列表中的下一个:

typescript
Copied
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 中提供了同样的模式,还带有 quorum 选项,可以查询多个提供商,并在它们达成一致后才接受结果,这让你在客户端内部就能做到跨提供商的一致性校验。

迁移流量的顺序比迁移速度更重要,原则是先读后写。读操作是无状态的,也容易验证,所以应尽早将读流量指向新端点,并对返回结果做差异比对。在你合约最繁忙的区块范围上对两个提供商都运行最重的查询,比如针对合约区块范围的 eth_getLogs 和针对核心合约的 eth_call,并比较响应结果。交易提交放到最后迁移,等读操作验证无误之后再进行,因为读失败只是重试一次,而写失败则会变成一张工单。

WebSocket 订阅需要多加一步。订阅绑定在创建它的连接上,因此不会自动故障转移,它会直接断开,需要你重新创建。计划在新端点上重新订阅,并用一个覆盖重连期间所经历区块范围的 eth_getLogs 查询回填这段缺口,确保不丢失任何事件。我们的WebSocket 最佳实践也建议保持订阅范围尽量窄,这样重新订阅和回填的成本都会更低。

并行运行期间,有两项指标值得放到仪表盘上跟踪。第一是区块高度滞后。两个健康的提供商在任一时刻都可能处于略有不同的链头位置,所以应对新端点持续落后于旧端点的情况报警,而不是对瞬时差异报警。第二是错误形态。限流响应在不同提供商之间有所不同。以 HTTP 为例,我们返回带有 Retry-After 请求头的 429;而在 WebSocket 上,同样的限制则表现为不带请求头的 JSON-RPC 429 错误。在新端点承载生产流量之前,先针对你使用的两种传输方式测试一下重试逻辑。

多数团队会让并行阶段承载一两天的生产流量,然后将新端点设为默认。旧端点作为回退配置保留,直到其计费周期结束。在整个过程中,回滚始终只是一次配置改动之遥,这也正是零停机在实践中的含义。问题仍然可能发生,只是永远不必触及用户。

如何判断新提供商是否表现良好?

你在并行阶段所做的比对,会成为基线。切换之后,继续观察切换前比对过的那些数字:成功率、p95 延迟和区块新鲜度。如果这次迁移值得做,其中至少有一项应该朝有利方向变化。

延迟方面的说法你也不必只凭信任。我们的实时 RPC 基准测试在不同链和地区上将我们与其他主流提供商做了对比,其背后的方法论是公开的,你可以在承诺之前,从自己所在地区复现这些数据。想深入了解这些数据为何能在负载下保持稳定,可以看看我们的边缘代理重构,其中详细介绍了每个请求首先经过的路由层。

如果你还在权衡提供商,而不是在验证某一个,我们的选择节点提供商指南和企业级 RPC 评估指南会涵盖在迁移问题出现之前就值得思考的那些问题。

迁移完成之后,也要保留并行运行期间的检查机制。用于验证切换的响应比对和延迟仪表盘,几个月后依然能发现提供商的性能退化和数据陈旧问题,而且它们已经搭建好了,无需重建。

准备好切换 RPC 提供商了吗?

无论你正在离开的是哪家提供商,以上内容都原样适用。

在 Alchemy 控制台中创建一个免费端点,今天就把你的预发布环境指向它。不需要签合同,不需要销售电话,也没有最低消费。免费套餐包含每月 3000 万计算单元,足以在真实生产流量上完成整个并行阶段的对比,并且同样的端点替换方式,在我们支持的100 多条链上都适用。

Alchemy 新闻通讯

第一时间获取发布信息

订阅我们的新闻通讯

获取 Alchemy 的最新产品更新和资源

A
O
D
+
超过 80,000 名订阅者

填写您的电子邮箱地址即表示您同意接收我们的营销通讯和产品更新。您确认 Alchemy 按照我们的隐私声明处理我们收到的信息。您可以随时取消订阅。