RPC 请求返回 429 是什么?限流、退避重试与配额排查 图 1
RPC 请求返回 429 是什么?限流、退避重试与配额排查 · 图 1

钱包或脚本连着公共 RPC 时,高峰期最常见的一行报错是 429 Too Many Requests。它不是链出了问题,也不是交易丢了,而是接口在说:你请求太快了,歇一下。读懂这行字,能省掉大量无效重试。

429 说的不是链的事

公共 RPC 网关按账户给请求频率和计算量设配额。Alchemy 在吞吐文档里写明,超出每秒计算单元上限时,HTTP 层返回 429 状态码,或通过 JSON-RPC 错误返回错误码 429;Infura 在超出每秒吞吐限额时同样回 429。要注意区分两种“没额度”:Infura 用满当日信用额度后返回的是 402 而不是 429,前者是速率限制,放慢就恢复;后者是当日用尽,只能提速方案或等次日重置。报错文本里的这句话值得多看一眼,它直接决定你下一步是等待还是去检查套餐。

重发的正确节奏:指数退避加随机抖动

官方文档推荐的处理方式是指数退避:第一次失败后等待约一秒重试,接着二秒、四秒成倍翻倍,每一档再叠加一个不超过一秒的随机毫秒数,直到封顶在某个最大间隔,文档给出的典型值是 32 或 64 秒。随机项的用意是防止同步波——大量客户端在同一个瞬间一起被限流、又按同一节拍一起重试,会把网关再次打进限流。HTTP 响应还可能带 Retry-After 头,给出建议等待秒数,官方仍建议在其上叠加退避而不是只依赖它。

普通用户为什么会碰到它

对普通用户来说,公共 RPC 的 429 更常表现为“网页应用卡顿”:行情组件转圈、交易状态长时间不刷新。它不改变你已经签发的交易——交易在广播那一刻就交给了节点网络,之后 RPC 有没有响应都不影响它上不上链,看状态请换浏览器直查,而不是在应用里反复刷新。处置顺序:先停止反复下拉刷新,密集点击只会继续撞限额;换用另一个 RPC 或自建节点把状态核实一遍,换源前完成链标识、区块高度、账户编号三项一致性核验,方法见 钱包 RPC 出错要换节点?先做链标识、高度与编号三项一致性核验;持续复现再去核对 RPC 套餐的限额设置。钱包与 RPC 的关系背景见 钱包连的是哪个 RPC:公共节点、专属接口和自建节点的取舍

开发者侧的根治:少发请求而不是猛重试

给应用和脚本的建议是砍请求量:启动时别把几十项数据一次拉满,用到哪查到哪;旧区块的结果缓存复用;用轮询循环盯新块很浪费配额——以太坊出新块的间隔本身有十几秒量级,比它还快的轮询只是刷限额,可改用订阅通知等变化推过来;多项余额用聚合调用合并成一笔。限流本质是资源配额问题,改请求结构比改重试代码更根本。另外值得建立的一个直觉:429 只说明“太快了”,不说明“错了”,它和签名错误、链不匹配这类真实故障是两种世界,前者放慢即可恢复,后者放慢一万倍也不会自己变好,把两者混在一起处理会既耽误修复又冤枉网关。同理,状态码 5xx 代表网关或服务端自身出了问题,换一个端点往往比原地等待更有效;而 429 的解法恰恰相反——换端点只是把撞墙的位置挪了挪,真正该做的是降频。

一条成本直觉:为什么应用会被自家请求拖垮

公共 RPC 的配额按每秒请求数或计算单元计量,而多数钱包界面发请求的动机只是看一眼余额和状态。把这些零散读取合并成一次聚合调用、把紧密轮询改成订阅通知,等于把几十份小票并成一份,同样的信息量消耗的配额低一个量级。同样的免费额度,有的应用全天顺滑、有的高峰期频频转圈,差距通常不在网络质量,而在请求结构。懂了这层,你就能判断社区抱怨的“钱包卡了”到底是链慢、节点慢,还是某个版本的脚本在刷接口。

本文为机制解释,不构成投资建议。对交易状态有疑问时,先以链上查询结果为准再决定是否重发,避免重复花费。