轮询与流式处理解析:区块链数据访问 |Quicknode🤖 新推出:《Quicknode 》AI 烹饪指南 10个经过验证的AI编程教程agents 。
查看食谱 通过 SOC 2 II 类认证 · ISO 27001
答案>了解区块链数据流>区块链数据的轮询与流式传输 // Tags
轮询与流式传输 WebSocket 区块链
简而言之:轮询是一种基于拉取的模式,即应用程序以固定间隔反复向区块链节点查询新数据。流式传输是一种基于推送的模式,新数据在链上生成后会自动传递给应用程序。轮询虽然实现简单,但会浪费资源、引入延迟,且存在数据丢失的风险。流式传输在规模化应用时更高效、更快且更可靠,但需要不同的基础设施。 对于大多数生产环境中的区块链应用程序而言,流式传输是更优的数据摄取方案。
简明解释
每个区块链应用都需要知道链上何时发生某些事件。钱包需要知道用户何时收到转账;DeFi 协议需要检测价格预言机何时更新;交易机器人需要在新的交易进入区块的瞬间就检测到它们;分析平台则需要在区块生成时立即处理每个区块。问题在于,你的应用如何获知这些事件。
在轮询模式下,您的应用程序会运行一个循环:调用 RPC 接口endpoint ,检查是否有新动态,处理任何新数据,等待固定时间间隔,然后重复上述步骤。这是大多数开发者最先学到的模式,因为它与 HTTP API 的工作原理自然契合。设置一个定时器,每 N 秒发送一次请求,处理响应。除了能够发送 HTTP 请求外,它不需要任何特殊的基础设施。
在流式处理中,您的应用程序只需建立一次连接或配置一次数据管道,新数据就会自动到达。无需循环、无需定时器、也无需重复请求。当生成一个新数据块时,数据会自动流向您的应用程序,而无需应用程序主动请求。应用程序的任务仅仅是处理随数据到达而传入的数据。
民意调查在实践中是如何运作的
监控新区块的典型轮询实现如下:您的应用程序调用“eth_blockNumber”获取最新区块,将其与上次处理的区块进行比较,通过“eth_getBlockByNumber”获取任何新区块,提取所需数据,并安排下一次轮询。 每次迭代至少需要一次 RPC 调用(用于检查最新区块号),并且可能还需要更多次调用(用于获取每个新区块的完整区块数据、交易收据和事件日志)。
轮询间隔是一个关键的设计决策。如果轮询过于频繁,就会在答案明明是“没有”的情况下,仍通过RPC请求(以及信用点)来询问“有什么新内容吗?”,从而造成资源浪费。以Ethereum 为例,该链每12秒生成一个区块,如果每秒进行一次轮询,意味着12次请求中有11次都无法返回有用的信息。 如果轮询过于稀疏,则会引入延迟。如果间隔为 30 秒,你可能要等到新区块生成 30 秒后才能发现它。此外,你可能在每个间隔内处理多个区块,从而导致系统负载不均。
轮询会带来若干可靠性风险。如果轮询因网络错误、速率限制或节点问题而失败,除非您的应用程序记录了上次处理的区块编号,并在下次成功轮询时回溯至该区块,否则可能会完全错过该区块。 如果应用程序崩溃或重启,它必须确定中断的位置并从该点恢复,同时处理停机期间生成的所有区块。如果轮询工作进程因处理延迟而落后,区块链末端与应用程序状态之间的差距就会扩大,而要赶上进度则需要处理积压的区块。
在高吞吐量的区块链上,轮询会变得尤为棘手。Solana 每 400 毫秒生成一个槽位。Arbitrum 和Base 每 250 毫秒生成一个区块。若以这些区块链的区块生成速率进行轮询,仅检查区块编号就需要每秒 2 到 4 次 RPC 请求,此外还需额外请求完整的区块数据。当扩展到多条区块链时,RPC 请求量(及成本)会随着区块链数量及其各自的区块生成速率呈线性增长。
流媒体在实际中的工作原理
WebSocket 订阅是区块链流式传输最简单的一种形式。您的应用程序会与一个节点建立持久的 WebSocket 连接,并发送订阅请求(例如带有“newHeads”参数的“eth_subscribe”)。节点会在每个新区块头生成后,立即通过该开放连接将其推送至您的应用程序。无需轮询,没有多余的请求,也没有延迟差距。
WebSocket 适用于简单的用例,但在大规模场景下存在显著局限性。连接是有状态的,可能会因网络问题、服务器重启或空闲超时而中断。当连接中断时,您的应用程序会遗漏重新连接前发生的任何事件,并且必须检测到断开连接、重新连接并填补数据缺口。在多个链上管理多个并发 WebSocket 连接会增加复杂性。 此外,WebSocket 订阅也不支持历史数据。如果您需要处理上周的区块,WebSocket 无法提供帮助。
专为流式传输设计的流服务能够解决这些限制。您的应用程序无需维护不稳定的 WebSocket 连接,而是配置一条由流服务端到端管理的数据管道。该服务连接到区块链节点,处理每个区块,应用您的过滤器,并将结果以保证送达的方式传输到您的目标位置。如果目标位置暂时不可用,该服务会缓存数据并重试。如果发生重组,该服务会发送更正数据包。 如果您需要历史数据,同一条数据管道可以从任意起始区块开始补填数据。
两种方法的比较
延迟是最明显的差异。在最佳情况下,轮询的延迟始终等于轮询间隔,但在实际应用中,由于处理时间和错误恢复,延迟会更长。流式传输会在数据一经生成时立即发送,通常在数据块生成后的几秒内完成。对于对延迟敏感的应用程序(如交易机器人或实时仪表盘),流式传输的速度明显更快。
资源效率是第二个主要区别。轮询生成的请求量与轮询频率成正比,无论是否存在新数据。一个每秒检查新区块的轮询进程,即使只关注一个每周触发一次的特定事件,每天仍会发出 86,400 次请求。流式处理消耗的资源与实际数据量成正比。如果没有任何事件符合您的过滤条件,则不会发送任何数据,您这边也不会消耗任何资源。
在规模化应用中,可靠性是区分这两种方法的关键。轮询方式要求您的应用程序自行维护状态跟踪、缺失检测、错误恢复和补发逻辑。每种边界情况(如数据块丢失、重复处理、重组、速率限制、节点故障转移)都必须在您的代码中进行处理。流式服务则在提供商端处理这些边界情况,提供无缺失、有序且去重的数据流,您的应用程序可以处理这些数据流,而无需担心基础设施的可靠性。
复杂性是需要权衡的。轮询在初期实现起来更为简单。 一个基本的轮询循环只需20行代码即可编写。但这种简单性具有欺骗性,因为经过生产环境验证的轮询需要错误处理、退避逻辑、状态管理、重组织检测以及监控,这些内容可能会使代码量激增至数百行。流式传输需要预先配置数据管道和能够接收推送数据的目标系统(如Webhook服务器或具有适当摄取逻辑的数据库),但一旦配置完成,其后续维护工作量要少得多。
轮询和流式传输有什么区别?
轮询和流式传输虽然都旨在解决同一个问题——将最新的链上数据引入应用程序,但两者的控制权关系恰好相反flow 。在轮询模式下,代码是主动方:它会反复调用RPCendpoint并查询是否有数据变化。而在流式传输模式下,提供方是主动方,会在每个新区块或匹配事件生成的一瞬间将其推送给您。下表从生产环境中最重要的几个维度对这两种模式进行了对比。
维度 | 民意调查 | 流媒体 |
|---|
数据flow | 基于拉取模式,您的应用会主动请求数据 | 基于推送,数据会自动发送 |
延迟 | 等于或长于抽样间隔 | 在块生成后的几秒内 |
资源使用情况 | 与轮询频率成正比,即使在空闲状态下也是如此 | 与实际数据量成正比 |
大规模环境下的可靠性 | 您的应用程序会处理数据缺口、重试和重组 | 提供商提供有序且已去重的数据流 |
历史数据 | 通过重新查询历史区块来提供支持 | 通过回填同一条管道来提供支持 |
设置的复杂程度 | 起步简单,强化却代价高昂 | 只需配置一次,后续维护工作量小 |
最适合 | 简单的脚本和低频检查 | 实时应用程序与高吞吐量区块链 |
如何选择轮询间隔?
如果进行轮询,轮询间隔应与所读取区块链的区块生成时间保持一致。如果轮询频率远高于区块生成速度,不仅会浪费请求,还可能触发速率限制;而如果轮询频率远低于区块生成时间,则会增加本可避免的延迟,并迫使工作节点同时处理多个区块。下表列出了各网络的典型区块生成时间及其对轮询实践的具体影响。
区块链 | 大致区块时间 | 民意调查的启示 |
|---|
Bitcoin | 大约10分钟 | 1到2分钟的间隔已经绰绰有余了 |
Ethereum | 大约12秒 | 每4至12秒进行一次轮询,以保持数据最新且避免资源浪费 |
BNB Smart Chain | 大约3秒 | 子块轮询会增加负载,但收益甚微 |
Base | 约 250 毫秒 | 轮询无法流畅地跟上;更倾向于流式传输 |
Solana | 约 400 毫秒 | 请求量大;强烈建议采用流式传输 |
在什么情况下仍应使用轮询?
对于大多数生产工作负载而言,流式处理是更优的默认选择,但在少数情况下,轮询仍是一个合理的选择。 一次性脚本、补录操作和不频繁的批处理任务,通常不值得专门为此构建托管管道。当您仅需按需获取单一值时,例如在用户操作前进行余额查询,且没有可订阅的连续数据流时,轮询也是可行的。不过,当数据的新鲜度和数据量确实重要时,权衡取舍会迅速发生变化,因此在确定具体方案之前,了解实时数据与历史数据之间的区别会很有帮助。
流式处理如何处理数据重组和数据丢失?
处理实时区块链数据最困难的部分并非正常流程,而是边界情况。链重组可能会覆盖应用程序已经处理过的区块,而连接中断则可能导致数据出现缺口。如果使用原始轮询或 WebSockets,您必须自行检测并修复这些情况。像 Quicknode Streams 这类托管服务会为你处理这些问题:它按最终性顺序交付数据,在发生链重组时发出更正数据包,并在目标不可用时进行缓冲和重试。正是这种差异,使得基于推送的交付在规模化运营时要容易得多。
常见问题解答
流媒体是否总是比民意调查更好?
并非总是如此。对于大多数需要连续、低延迟数据的生产应用而言,流式传输在效率和可靠性方面更具优势。但对于一次性脚本、简单的余额查询或低频任务,轮询方式完全足够,且更易于配置。正确的选择取决于数据必须有多及时,以及处理的数据量有多大。有关推送式模型的入门指南,请参阅“什么是区块链数据流式传输”。
我应该多久轮询一次 RPCendpoint ?
请将轮询间隔与区块链的区块生成时间相匹配。在Ethereum 上,每 4 到 12 秒轮询一次既能保持数据最新,又不会浪费调用次数。在Solana 或Base 这样的高速区块链上,按区块生成频率进行轮询并不现实,流式处理更为合适。如果轮询频率远高于区块生成频率,通常不会返回新数据,反而会消耗请求配额。请参阅RPC 请求的工作原理,了解每次调用的具体内容。
轮询的成本是否高于流式传输?
在大规模场景下往往确实如此。轮询会按照固定时间表生成请求,无论是否有新数据,因此一个繁忙的轮询工作者每天可能发出数万次调用,却只捕获到寥寥几个事件。流处理消耗的资源与实际符合过滤条件的數據量成正比,这通常意味着更少的无效请求,从而降低了持续性工作负载的成本。
在重组过程中,我的数据会发生什么变化?
如果仅使用简单的轮询或原始 WebSockets,重组织可能会导致您的应用程序仍持有在规范链上已不存在的交易。受管流式服务能够检测到重组织,并发送更正数据包,从而确保您的状态保持一致。了解吞吐量与延迟之间的权衡,也有助于您决定在将数据视为已结算之前应等待多长时间。
我能从流媒体服务中获取历史数据吗?
是的。与仅从连接时刻起推送新事件的 WebSocket 订阅不同,完整的流式处理管道可以使用相同的配置,从任何过去的区块开始补发数据。这使您能够回放历史数据,然后无缝过渡到实时数据,而无需运行两个独立的系统。
Quicknode 如何同时支持这两种模式
Quicknode其核心 API在所有受支持的链上均支持通过 HTTP RPC 端点进行轮询,以及通过 WebSocket 连接进行实时订阅。对于使用轮询的应用程序,Quicknode 关于高效 RPC 请求的指南介绍了如何最大限度地减少无用调用、实现正确的错误处理以及管理速率限制的最佳实践。
对于希望摆脱轮询机制的应用程序,Quicknode (Streams )提供了一条完全托管的数据流管道。Streams 可提供实时区块链数据,具备交付保证、最终性排序处理、自动重组处理以及服务器端过滤功能,且无需您的应用程序维护 WebSocket 连接或轮询基础设施。Streams 支持将数据传输至webhooks 、PostgreSQL、Snowflake、Amazon S3、Azure Storage 等平台,使其能够适应任何后端架构。Quicknode的文档中提供了 WebSocket 订阅与Streams 之间的直接对比指南,涵盖了从轮询或基于 WebSocket 的架构过渡的团队需要考虑的权衡因素和迁移路径。
延伸阅读