挑 Solana RPC 服务商,你想 benchmark 它们。营销页不够;SLA 承诺不够;你要针对真实负载的真实测量。但你网上找到的大多数公开 RPC benchmark 都是坏的——错的方法、错的指标、要么就是过时。
这篇是给 Solana RPC 用、产生可行结论的 benchmark 方法论。测什么、怎么测、让 benchmark 没用的常见错误。
Benchmark 的错方式
几个产生坏结果的常见模式:
单次延迟测试。 "我对每个 RPC 调一次 getSlot;最快的是 X。"没用。一次测量是噪音。
非高峰测量。 凌晨 3 点没事时 benchmark,告诉你的是 RPC 在闲置条件下表现。生产关心高峰。
只看平均。 "平均延迟 200ms。"平均藏长尾。生产关心 P95 和 P99。
合成负载。 用跟你实际负载对不上的造出来的流量做 benchmark,跑出来的结论跟你的情况没关系。
对比不同 commitment 等级。 苹果对橘子。一个 RPC 用 processed 测、另一个用 confirmed 测,你不在 benchmark RPC。
不算客户端方差。 你客户端到每个 RPC 的网络重要。从一个客户端位置对比 RPC 告诉你的是那个客户端;稳健结论要多个客户端位置。
实际该测什么
对生产决策重要的指标:
端到端交易延迟。 从"我调 sendTransaction"到"交易已上链到某个块"。不只是 sendTransaction 的 HTTP 响应时间。
P95 和 P99 延迟。 平均给营销用。生产关心最坏情况行为。
拥堵下延迟。 网络高峰时段测、不是非高峰。有趣的对比是负载高时发生什么。
有效 fill 质量(交易负载)。 不只是交易上不上链、而是什么价格上的。对比 AMM 数学预期。
失败率。 多频繁交易静默失败?每笔失败交易成本多少?
每笔上链交易的成本。 总成本(费 + RPC 定价)除以成功上链数。跟每请求成本不同。
尾部行为。 最坏情况是什么?P99.9?再外?
行得通的方法论
可行方法:
1. 定义你的负载。 什么交易?什么仓位?什么网络条件?具体。
2. 设并行提交。 配同样负载,同时(或交替)把相同交易提交到 N 个 RPC。大多数语言能容易处理。
3. 在代表性条件下跑。 覆盖营业时段和非高峰。覆盖工作日和周末。具体覆盖拥堵窗口。
4. 样本量重要。 单天测量太噪。最少跑一周拿稳健结果。
5. 跟踪每笔签名级别的结果。 每笔交易带完整上下文记日志:哪个 RPC、签名、尝试时间、上链时间、slot、结果。
6. 分析分布、不只看平均。 直方图、百分位拆解、尾部分析。生产环境的体验由尾部决定。
7. 算成本。 整个样本上每笔上链交易的总成本。一些 RPC 每请求便宜但每上链贵。
具体测什么
Solana 这块:
发送延迟。 从你 sendTransaction 调用到交易上链某块的时间。HTTP round-trip(RPC 接受)和链上上链都要测。
确认延迟。 从接受到 "confirmed" commitment 的时间。
读延迟。 读量大的负载,测 getAccountInfo 这种。跟写延迟不同,但混合负载里也重要。
拥堵期行为。 Solana 有可预测的拥堵窗口(代币发币、NFT mint、市场波动)。这些时候测。
Stake-weighted QoS 有效性。 直接测难,但能从拥堵下的上链行为推断。Stake-weighted 关系强的 RPC,在那种负载下应该更可靠上链。
三明治被夹敞口。 交易负载,对比实际 fill 和 AMM 数学预期。系统性差距 = 被夹税。Anti-MEV 路由的 RPC 应该差距更小。
实现草图
TypeScript 基础 benchmark harness:
import { Connection, Keypair, Transaction, SystemProgram } from "@solana/web3.js";
const RPCS = [
{ name: "rpc1", url: "https://...", connection: null },
{ name: "rpc2", url: "https://...", connection: null },
];
for (const r of RPCS) {
r.connection = new Connection(r.url, "processed");
}
async function submitToAll(tx, signers) {
const promises = RPCS.map(async (r) => {
const start = Date.now();
try {
const sig = await r.connection.sendTransaction(tx, signers, {
skipPreflight: true,
maxRetries: 0,
});
const status = await r.connection.confirmTransaction(sig, "confirmed");
const end = Date.now();
return {
rpc: r.name,
signature: sig,
latency_ms: end - start,
outcome: status.value.err ? "failed" : "success",
err: status.value.err,
};
} catch (e) {
return {
rpc: r.name,
outcome: "error",
err: e.message,
};
}
});
return Promise.all(promises);
}
// 周期提交,记录结果
生产版本要加:
- 持久化日志到数据库或文件
- 真负载生成、不只是转账
- 多区域客户端测试
- 收集后做统计分析
- 成本跟踪
产生坏 benchmark 的错误
不同日子做对比。 网络条件会变。同时间对比 RPC。
不同交易类型。 转账 benchmark 跟复杂 DeFi 调用不同。挑一种一致的交易类型。
不同的 priority fee。 Priority fee 高低直接影响上链延迟。跨 RPC 对比时,各家的 priority fee 必须保持一致。
同一个 blockhash。 跨 RPC 复用 blockhash 你在测竞态条件、不是 RPC 性能。每次提交都该有自己的新 blockhash。
算 warmup。 前几次调用有连接建立开销。算统计前丢掉前 N 次。
忽略方差。 两个都平均 200ms 的 RPC 分布可能差很多。看分散。
解读结果
有数据后:
哪个 RPC P95 最好? 经常跟"哪个平均最好"是不同问题。
哪个 RPC 尾部最低? P99 及更差。生产敏感性活在这。
哪个 RPC 每笔上链交易成本最好? 总成本除以成功发送数。小心对比的是标价、不是有效成本。
哪个 RPC 行为最一致? 方差重要。可预测的 RPC 常比有时更快的有用。
哪个 RPC 负载下降级最少? 同一 RPC 高峰 vs 非高峰行为对比。降级少 = 更生产级。
这周可以做什么
评估 RPC:
- 挑 2-3 个候选。 多了 benchmark 工作太多。
- 精确定义你的负载。 测什么必须匹配生产做什么。
- 设并行提交。 最少跑一周。
- 每笔签名跟踪、带丰富元数据。 让你能事后分析。
- 分析分布。 不只看平均。
- 算每笔上链交易的成本。 最诚实的指标。
- 做决定。 别永远 benchmark;挑、承诺、监控抓回归。
BoltTx 当 benchmark 候选
要在 benchmark 里包 BoltTx:
import { Connection } from "@solana/web3.js";
const connection = new Connection(
"https://bolttx.io/?api-key=YOUR_API_KEY",
"processed"
);
免费档注册。免费档够跑有意义的周级 benchmark。BoltTx 侧每笔签名级别的投递遥测帮分析。
常见问题
Benchmark 该跑多久? 最少一周。日级方差太高;周级抓住大多数模式。
该对比多少 RPC? 两三个。多了不好操作;少了不给你替代。
该公开 benchmark 结果吗? 方法论自信的话——是的,社区受益于诚实数据。方法论不稳的话你误导多于帮助。
对比的好基线 benchmark 是什么? "公共 mainnet-beta 端点"是"不努力能拿到什么"的合理基线。明显比那好就有意义。
能信服务商的营销 benchmark 吗? 怀疑。方法论经常不清楚。自己跑。