摘要
Solana RPC 是您的应用用来读取账户、发送交易和订阅链上事件的 JSON-RPC 接口。本概览涵盖端点形态、您最常调用的方法,以及从演示环境迁移到线上应用时通常最先出问题的设置。它还解释了何时共享端点足够,以及何时专用 Solana 节点是更合适的选择。
Solana RPC 是您的应用程序用来与 Solana 节点通信的 JSON-RPC 接口。Solana 应用中的每个钱包余额、代币账户、交易提交和日志订阅最终都会变成一次 RPC 调用。本概览解释了端点的样子、您实际会调用哪些方法,以及在上线前如何在共享端点和专用节点之间做出选择。
如果您是因为搜索 Solana RPC 文档而来到这里,简短版本是:Solana 通过 HTTP 暴露 JSON-RPC API 用于请求/响应调用,并通过 WebSocket 用于订阅。您将客户端指向一个端点 URL,发送 JSON-RPC 请求,然后得到 JSON 响应。有趣的决定在于您使用哪个端点、如何处理承诺级别,以及如何在负载下保持连接健康。
何时共享 Solana 端点足够(何时不够)
大多数团队应该从共享或公共端点开始,只有在出现特定信号时才迁移到专用基础设施。在您花时间进行节点运维之前,请将此作为快速分诊。
| 您看到的信号 | 共享端点通常足够 | 考虑专用 Solana 节点的时候 |
|---|---|---|
| 流量特征 | 低到中等请求量,主要是读取 | 持续高请求量、突发流量或大量并发 WebSocket 订阅 |
| 工作负载类型 | 钱包余额、简单转账、仪表盘 | 索引器、交易系统、大量调用 getProgramAccounts 或 getSignaturesForAddress 的后端 |
| 延迟敏感度 | 能容忍共享排队 | 延迟敏感路径,需要可预测的放置 |
| 数据需求 | 仅最近状态 | 归档式历史查询、大型日志扫描或大量 getBlock 使用 |
| 运维控制 | 您不想运行节点 | 需要隔离、自定义限制或私有端点 |
如果您仍在第一列,托管共享端点是最快的路径。OnFinality 提供 Solana RPC 作为托管 API,您可以查看 Solana 网络详情 了解当前端点和传输支持。如果您在第二或第三列,请在假设需要自己运行硬件之前阅读下面的专用节点部分。
端点形态:HTTP 和 WebSocket
Solana RPC 端点是一个 URL。HTTP 端点处理请求/响应调用。WebSocket 端点处理订阅,例如 accountSubscribe、logsSubscribe 和 slotSubscribe。OnFinality 的公共 Solana 端点遵循此模式:
- HTTP:
https://solana.api.onfinality.io/public - WebSocket:
wss://solana.api.onfinality.io/public-ws
对于生产应用,您通常会使用 API 密钥或专用端点,而不是公共 URL。公共端点对于快速测试、原型以及在将请求接入应用之前验证请求形态是否正确非常有用。
一个最小配置如下所示:
import { Connection, PublicKey } from "@solana/web3.js";
const connection = new Connection(
"https://solana.api.onfinality.io/public",
{ commitment: "confirmed" }
);
const balance = await connection.getBalance(
new PublicKey("11111111111111111111111111111111")
);
console.log(balance);
commitment 选项是最常见的困惑来源之一,因此值得有意设置,而不是接受默认值。
承诺级别以及它们为何会改变您的结果
Solana 不会立即最终确定区块。交易会经历 processed、confirmed 和 finalized 状态。您传递给 RPC 调用的承诺级别告诉节点在返回数据之前您想要多少确定性。
| 承诺级别 | 实际含义 | 典型用途 |
|---|---|---|
processed | 最快、最不确定;节点已看到区块,但可能仍被跳过 | 需要最新可能状态且能容忍回滚的 UI |
confirmed | 绝大多数质押已投票;不太可能回滚 | 大多数应用读取和交易确认 |
finalized | 最大确定性;区块已扎根 | 会计、结算以及任何不可逆转的内容 |
一个实用的模式是:对于面向用户的余额,使用 confirmed 读取;当您记录不可更改的值时,使用 finalized。在单个工作流中混合承诺级别是常见的错误来源:在 processed 读取的余额和在 finalized 确认的交易可能会在短时间内不一致。
您最常调用的核心 Solana JSON-RPC 方法
您不需要记住完整的方法列表。大多数 Solana 应用反复使用一小部分方法,其余方法仅出现在特定功能中。
| 方法 | 返回内容 | 注意事项 |
|---|---|---|
getBalance | 账户的 Lamport 余额 | 承诺级别会在槽边界附近改变值 |
getAccountInfo | 账户数据、所有者、lamports | 大账户会增加响应大小 |
getTokenAccountsByOwner | 钱包的 SPL 代币账户 | 对于拥有许多代币账户的钱包可能很重 |
getTransaction | 按签名获取单个交易 | 如果节点未看到或已修剪,则返回 null |
getSignaturesForAddress | 地址的最近签名 | 分页很重要;不要请求无界范围 |
getLatestBlockhash | 用于构建交易的最近区块哈希 | 区块哈希会过期;在发送时间附近获取 |
sendTransaction | 提交已签名交易 | 显式处理预检错误和重试 |
simulateTransaction | 试运行交易 | 在发送任何转移资金的操作之前很有用 |
getProgramAccounts | 程序拥有的账户 | 开销大;积极过滤或预期超时 |
一个直接的 JSON-RPC 调用如下所示:
curl https://solana.api.onfinality.io/public \
-X POST \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "getBalance",
"params": [
"11111111111111111111111111111111",
{"commitment": "confirmed"}
]
}'
如果您正在调试客户端库,首先发送原始 JSON-RPC 请求是快速区分库问题和端点问题的方法。
WebSocket 订阅:停止轮询后会发生什么变化
在循环中轮询 getSlot 或 getBalance 很简单但浪费。WebSocket 订阅让节点将更新推送给您。权衡在于连接管理:订阅可能会断开,您需要重连逻辑。
const ws = new WebSocket("wss://solana.api.onfinality.io/public-ws");
ws.onopen = () => {
ws.send(JSON.stringify({
jsonrpc: "2.0",
id: 1,
method: "logsSubscribe",
params: [
{ mentions: ["YourProgramPublicKeyHere"] },
{ commitment: "confirmed" }
]
}));
};
ws.onmessage = (event) => {
const message = JSON.parse(event.data);
// Handle notification payloads here
};
两个操作注意事项。首先,订阅是有状态的:如果套接字关闭,您的订阅就消失了,必须重新建立。其次,从未清理的订阅会持续消耗资源,因此当组件卸载或任务完成时取消订阅。
常见故障模式以及如何解读它们
大多数 Solana RPC 问题属于几种模式。识别症状可以节省时间。
| 症状 | 可能原因 | 首先检查什么 |
|---|---|---|
429 或限流响应 | 请求速率超过端点的允许量 | 批量大小、轮询频率以及您是否重试过于激进 |
getProgramAccounts 超时 | 查询对端点来说太宽泛 | 添加过滤器、减少数据大小或迁移到专用节点 |
交易返回 Blockhash not found | 区块哈希在发送前过期 | 在发送前立即获取新的区块哈希 |
| 交易模拟失败 | 账户状态改变或指令无效 | 重新运行 simulateTransaction 并检查日志 |
| WebSocket 停止传递 | 套接字断开或订阅过期 | 添加重连和重新订阅逻辑 |
| 余额不一致 | 不同调用的承诺级别不同 | 按工作流标准化承诺级别 |
一个有用的习惯是记录原始 JSON-RPC 错误代码和消息,而不仅仅是通用的“请求失败”。Solana 错误代码足够具体,可以为您指明修复方向。
共享端点 vs 专用 Solana 节点
一旦您了解自己的工作负载,构建与购买的问题就变得具体了。运行自己的 Solana 节点意味着配置硬件、跟上客户端发布和管理存储增长。托管专用节点为您提供隔离的端点,而无需承担运维负担。托管共享端点则两者都不需要,就能为您提供可用的 RPC API。
| 方法 | 您管理的内容 | 适合 |
|---|---|---|
| 公共端点 | 无需管理,但预期共享限制 | 原型、测试、低流量脚本 |
| 托管共享 RPC(OnFinality) | 无需管理;您获得一个 API 端点 | 中等、主要是读取流量的生产应用 |
| 托管专用节点(OnFinality) | 配置选择,而非硬件 | 高流量读取、大量订阅、隔离需求 |
| 自托管节点 | 硬件、升级、监控、存储 | 有特定合规或控制要求的团队 |
OnFinality 提供 Solana RPC 作为托管 API,并在您需要隔离时提供专用节点。您可以在 RPC 定价 页面比较选项,如果您还在其他链上运行,可以查看 支持的 RPC 网络。如果您仍在提供商之间做决定,RPC 提供商选择指南 会介绍评估标准。
实用的上线检查清单
在将生产流量指向任何 Solana 端点之前,请确认以下事项:
- 承诺级别按调用显式设置,而不是留给默认值。
- 您有处理
getProgramAccounts和其他重读取的策略,例如过滤器或专用节点。 - 交易发送会获取新的区块哈希并处理预检错误。
- WebSocket 客户端在断开后重连并重新订阅。
- 您记录原始 JSON-RPC 错误代码以便调试。
- 您知道预期的请求量,并将其与端点层级匹配。
- 您有备用端点或关键路径的故障转移计划。
如果您无法回答第六项,请从共享端点开始,并在承诺专用基础设施之前进行测量。
关键要点
- Solana RPC 是一种 JSON-RPC API,可通过 HTTP 用于调用,通过 WebSocket 用于订阅。
- 承诺级别(
processed、confirmed、finalized)直接改变您收到的数据;请有意设置它们。 - 一小部分方法覆盖大多数应用,但像
getProgramAccounts这样的重读取需要过滤器或专用容量。 - WebSocket 订阅减少轮询,但需要重连和清理逻辑。
- 对于中等流量,选择共享托管端点;当您需要隔离或处理重读取时,选择专用 Solana 节点。
- OnFinality 提供 Solana RPC 作为托管 API;查看 Solana 网络详情 了解当前端点和传输支持。
常见问题解答
Solana RPC 端点格式是什么?
Solana RPC 端点是一个 URL,接受通过 HTTP 的 JSON-RPC 请求,并有一个单独的 WebSocket URL 用于订阅。OnFinality 的公共 Solana 端点是 https://solana.api.onfinality.io/public(HTTP)和 wss://solana.api.onfinality.io/public-ws(WebSocket)。生产应用通常使用 API 密钥或专用端点,而不是公共 URL。
我应该使用哪个承诺级别?
对于大多数面向用户的读取和交易确认,使用 confirmed;对于不可逆转的值(如会计条目),使用 finalized。仅当您需要最新可能状态并能容忍区块被跳过的可能性时,才使用 processed。
为什么 getProgramAccounts 会超时?
它会扫描程序拥有的账户,如果没有过滤器,结果集可能非常大。添加过滤器,例如数据大小或 memcmp 约束,仅请求您需要的字段,或者将此工作负载迁移到有更多余量的专用节点。
我需要专用 Solana 节点吗?
不一定。从共享托管端点开始,并测量您的请求量、订阅数量和重读取频率。当您需要隔离、可预测的容量,或者您反复触及共享基础设施的限制时,再迁移到专用节点。
如何处理 WebSocket 断开连接?
将订阅视为有状态且可丢弃的。添加重连逻辑,在重连时重新订阅,并在消费者关闭时取消订阅。记录断开原因,以便区分网络问题和端点侧限制。
我可以将 OnFinality 用于 Solana 和其他链吗?
可以。OnFinality 在多个网络上提供 RPC API 访问。查看 支持的 RPC 网络 了解当前列表,查看 RPC 定价 了解计划详情。如果您需要隔离容量,请查看 专用节点。