Beacon API 是以太坊共识层信标节点对外提供的 REST 接口,在 ethereum/beacon-APIs 仓库中标准化,并按端点分别进行版本管理。它允许验证者客户端、区块浏览器和工具通过 HTTP 查询链状态、提交区块和证明、订阅事件,以及检查节点健康状况。本文解释了心智模型、端点分组、JSON 与 SSZ 内容协商,以及一套可对任意节点重复执行的诊断流程。文章还将有文档记录的协议行为与需要您自行测量的指标区分开来,并在涉及提供商选择时指向端点选择指南。
范围与两个同名的 Beacon API
本页介绍的是 以太坊 Beacon API:由共识层信标节点实现对外提供的 RESTful HTTP 接口,在 ethereum/beacon-APIs 仓库中定义,并以 OpenAPI 文档形式呈现。它是验证者客户端与其信标节点通信所使用的接口,也是区块浏览器、索引器和监控工具读取共识数据所使用的接口。
这个名称存在重载。浏览器 navigator.sendBeacon() Web API 与此无关:它在页面卸载时发送一个小型异步 POST 请求,通常用于分析统计。如果您是来找那个的,MDN 和 W3C 的 Beacon 文档才是正确的参考。下文全部内容均涉及以太坊共识 REST API,这也是与节点运维人员和验证者基础设施相关的含义。
- 以太坊 Beacon API:REST/HTTP,默认 JSON,部分端点支持 SSZ,按端点分别进行版本管理。
- 浏览器 Beacon API:仅有一个
navigator.sendBeacon()方法,不期望响应,在 Web Worker 中不可用。 - 本文讨论的是前者;两者仅共享名称,别无其他关联。
开始前的假设
本流程假设您可以访问一个正在运行的信标节点(无论是自托管还是通过托管 RPC 提供商),并且您知道其 HTTP API 是暴露在 localhost 上还是位于网关之后。规范本身不鼓励公开暴露信标节点 API,因为若干端点会触发繁重处理,可能被滥用于拒绝服务攻击。除非您已在前面添加了身份验证和速率限制,否则请将该 API 视为内部服务。
您还需要 curl,以及对于 SSZ 示例,需要一个能将二进制输出写入文件的工具。只读诊断不需要验证者密钥;提交区块或证明确实需要验证者客户端和签名设置,这不在本文范围内。
心智模型:信标节点、验证者客户端与 REST 边界
信标节点通过与对等节点通信来维护信标链的状态。从概念上讲,它不持有验证者密钥对。验证者客户端是一个独立进程,持有私钥,决定要签名什么,并使用信标节点的 API 获取职责、生成区块和证明,以及广播已签名的消息。因此,该 API 既是读取接口(链数据、配置、节点信息),也是写入接口(交易池提交、区块和证明发布)。
端点各自独立进行版本管理。所有 v1 端点与所有 v2 端点之间没有关系;您必须阅读每个路径上的版本。响应在顶层 data 键下返回请求的数据,同级键中可包含可选的元数据。字段可以在不提升版本的情况下添加,但删除或更改已列出的字段格式则需要提升版本。正是这条规则使得构建忽略未知字段的客户端是安全的。
端点分组及其用途
OpenAPI 文档按用途对端点进行分组。了解这些分组有助于您选择正确的路径,并避免意外暴露调试路由。
Beacon 组查询信标链状态和对象:区块头、区块、状态和交易池。Config 组返回链配置、规范值和分叉计划。Node 组返回节点身份和健康信息,例如版本和同步状态。Validator 组面向验证者客户端,包含一个可工作的验证者实现所需的最小端点集,以及有文档记录的验证者流程。Events 组提供事件订阅,通常通过服务器发送事件(SSE)实现。Rewards 组查询奖励和惩罚。Debug 组明确标记为不对外公开。
- 只读链查询:Beacon 组。
- 分叉计划和规范常量:Config 组。
- 健康和身份检查:Node 组。
- 验证者职责、区块生产和提交:Validator 组。
- 流式更新:Events 组。
- 仅用于诊断:Debug 组,请保持私有。
JSON、SSZ 与内容协商
默认情况下,请求发送和接收 JSON,因此在涉及请求体时请包含 Content-Type: application/json 和 Accept: application/json。部分端点还可以接受或返回 SSZ,即共识层序列化格式。要发送 SSZ,请设置 Content-Type: application/octet-stream。要在响应中优先使用 SSZ,请设置一个将 SSZ 排在 JSON 之前的 Accept 头,例如 application/octet-stream;q=1.0,application/json;q=0.9。
服务器契约是明确的:如果请求的 Content-Type 不受支持,返回 415;如果无法以可接受的格式生成响应,返回 406。如果未发送 Accept 头,则假定为 JSON。服务器必须在 Content-Type 中指明响应格式。这在您编写客户端时很重要,因为返回 200 但内容类型意外是一个 bug,您应该将其暴露出来,而不是盲目解析。
curl -sS -D - -o /dev/null \
-H 'Accept: application/json' \
"$BEACON_URL/eth/v1/node/version"可运行诊断:四次调用探测信标节点
以下序列对您有权查询的任何节点都是安全的。它检查可达性、身份、同步状态和一次链读取,并记录每次调用的 HTTP 状态和内容类型,以便您区分传输问题和格式问题。将 BEACON_URL 设置为节点的基 URL,例如本地节点使用 http://127.0.0.1:5052,或您的提供商的 HTTPS 基 URL。
运行每次调用并记录状态码和 Content-Type。四次调用均返回 200 和 application/json 是预期的健康结果。415 或 406 指向您的请求头,而非节点。连接错误指向 URL、防火墙或 TLS。同步端点返回 503 在节点仍在追赶时是正常的。
export BEACON_URL="http://127.0.0.1:5052"
# 1. Identity and version
curl -sS -w '\nHTTP %{http_code} %{content_type}\n' \
-H 'Accept: application/json' \
"$BEACON_URL/eth/v1/node/version"
# 2. Sync status
curl -sS -w '\nHTTP %{http_code} %{content_type}\n' \
-H 'Accept: application/json' \
"$BEACON_URL/eth/v1/node/syncing"
# 3. Chain configuration (fork schedule)
curl -sS -w '\nHTTP %{http_code} %{content_type}\n' \
-H 'Accept: application/json' \
"$BEACON_URL/eth/v1/config/fork_schedule"
# 4. A recent block header by id
curl -sS -w '\nHTTP %{http_code} %{content_type}\n' \
-H 'Accept: application/json' \
"$BEACON_URL/eth/v1/beacon/headers/head"验证:正确结果的样子
一次正确的运行会在每个端点上返回带有顶层 data 键的 JSON 响应体。版本端点返回节点身份字段。同步端点返回一个布尔值和头部槽位信息;如果节点未同步,头部槽位将落后于网络。分叉计划返回配置的分叉和纪元。区块头端点返回头部区块头及其根和槽位。
将您的观察结果记录在表格中,以便运行可复现,并可在不同节点或不同时间之间进行比较。不要填写您未观察到的数字;下表是模板,不是结果集。
- | 检查项 | 端点 | 预期状态 | 预期内容类型 | 观察值 |
- | 身份 |
/eth/v1/node/version| 200 | application/json | (记录) | - | 同步 |
/eth/v1/node/syncing| 200 | application/json | (记录) | - | 分叉 |
/eth/v1/config/fork_schedule| 200 | application/json | (记录) | - | 头部区块头 |
/eth/v1/beacon/headers/head| 200 | application/json | (记录) |
自行测量延迟和一致性
提供商的性能声明不可移植,因此请针对您自己的工作负载进行测量。一个简单的方法是重复对一组固定的只读调用计时,并记录分布,而不仅仅是平均值。使用 curl 的 time_total 或一个小脚本,运行足够多的迭代以观察尾部行为,并将冷连接与复用连接分开。
下面的脚本对同步端点计时并打印每个样本。针对两个候选端点运行它,并比较中位数和最大值。保持端点之间的样本大小和时间窗口相同,并记录一天中的时间,因为共识节点在槽位边界附近最繁忙。
import json, statistics, time, urllib.request
BEACON_URL = "http://127.0.0.1:5052"
PATH = "/eth/v1/node/syncing"
N = 30
samples = []
for _ in range(N):
start = time.perf_counter()
req = urllib.request.Request(BEACON_URL + PATH, headers={"Accept": "application/json"})
with urllib.request.urlopen(req, timeout=10) as resp:
body = json.loads(resp.read())
elapsed_ms = (time.perf_counter() - start) * 1000
samples.append(elapsed_ms)
print(f"{elapsed_ms:8.1f} ms synced={body['data'].get('is_synced')}")
print(f"median={statistics.median(samples):.1f} ms max={max(samples):.1f} ms")常见 Beacon API 故障排查
大多数故障可归为几类:基 URL 或路径版本错误、请求头不匹配、节点未同步,或端点被有意限制。在假设节点损坏之前,请按此顺序逐一排查。
如果收到 404,请对照节点支持的 API 版本的 OpenAPI 文档检查路径中的端点版本;版本是按端点管理的,旧节点可能未实现较新的路径。如果收到 415 或 406,原因是您的 Content-Type 或 Accept 头。如果读取成功但数据看起来陈旧,请检查同步端点和头部槽位。如果验证者客户端无法启动,请验证它指向正确的信标节点 URL,并且所需的验证者端点可达。
- 连接被拒绝或超时:URL、端口、防火墙或 TLS 终止。
- 404:路径错误或该节点不支持该端点版本。
- 415/406:请求或响应格式协商问题。
- 数据陈旧:节点正在同步或落后于网络头部。
- 403/401:节点前面的网关或提供商身份验证层。
局限性与权衡
Beacon API 并非设计为公共互联网服务。规范警告称,在没有额外安全层的情况下暴露它会使节点容易通过繁重端点遭受拒绝服务攻击。如果您需要公共读取访问,请在其前面放置一个缓存、限流的网关,并仅暴露您需要的读取端点。
SSZ 支持是部分的:只有一部分端点接受或返回它,并且每个端点都有单独说明。JSON 是工具和调试的安全默认值。版本管理是按端点的,因此将所有路径固定到单一 API 版本没有意义;相反,请阅读您依赖的每个路径上的版本,并针对您实际运行的节点版本进行测试。
最后,该 API 是节点本地接口,不是共识保证。两个健康的节点在同一时刻可能返回略有不同的头部。设计客户端时应容忍这一点,而不是将任何分歧视为错误。
生产使用的后续步骤
一旦诊断通过,就从临时调用转向受监控的集成。将上述四项检查包装在健康探测中,对非 200 响应和同步滞后发出警报,并记录内容类型,以便格式回归可见。对于验证者基础设施,请遵循有文档记录的验证者流程,而不是手动拼装端点。
如果您不想自己运营共识节点,请比较托管选项并使用相同流程进行测量。从 OnFinality 网络目录开始查看支持的链,查看 RPC 定价以了解吞吐量和请求限制,并在需要可预测容量或私有 API 暴露时考虑专用节点。对于具体的端点和提供商建议,请使用 RPC Assistant,而不是猜测公共 URL。
- 在 OnFinality 网络目录 中浏览支持的链。
- 在确定工作负载规模之前,查看 RPC 定价和请求限制。
- 评估 专用节点 以进行私有或高流量的 Beacon API 访问。
- 查看更广泛的 RPC 服务概览 和 RPC 端点指南。