监控工具怎么知道事件发生了:轮询与订阅推送的分工 图 1
监控工具怎么知道事件发生了:轮询与订阅推送的分工 · 图 1

同样是新交易出现时提醒我,工具的实现可以完全不同:有的每隔几秒去问一次有什么新东西,有的挂在节点上等推送。理解这两种模式,能解释很多日常困惑——为什么面板有时比区块浏览器慢半拍、为什么重连之后提醒全停了、为什么重组后已经亮过的绿灯会反悔。

轮询:一问一答

最常见的方式是 HTTP 轮询:程序定时调用查询接口,比如查最新区块高度、查某地址的交易数、查交易回执。它的逻辑简单——上次问到的位置和新位置之间的差异,就是新发生的事。优点是任何 RPC 端点都支持、程序好写、网络环境友好;代价有二:一是延迟受间隔限制,两秒问一次就最多晚两秒知道;二是大量重复问题浪费双方资源,公共 RPC 的速率限制很多时候就是被问太多触发的。

实践中两种模式经常并存:用订阅拿实时性,用低频轮询做对账兜底——比如每隔几分钟核对一次区块高度是否连续、关键交易是否仍在最长链上。订阅通道一旦悄悄失效,兜底轮询就是唯一能暴露静默故障的眼睛。

订阅:把问换成推

Geth 等节点提供基于 WebSocket 的发布订阅通道:先用 eth_subscribe 注册感兴趣的主题,节点有新事件就主动下发。常用主题包括 newHeads(每个新区块头)、logs(匹配条件的事件日志,例如某合约发出的 Transfer)、新的待处理交易和节点同步状态。EIP-1193 在钱包接口侧也为此定义了 message 事件和 eth_subscription 结构,页面拿到订阅标识与推送数据。相比轮询,订阅能把发现延迟压到接近出块间隔本身,代价是 WebSocket 连接本身脆弱——代理超时、扩展重载、手机切后台、网络切换都可能悄悄掐断它。

两个必须处理的问题

第一,连接断了,订阅就死了。WebSocket 的重连不等于订阅恢复:旧连接上的订阅标识随连接一起作废,重连后必须重新注册主题,否则你会处在一个一切正常但不再收到任何推送的静默故障里。健壮的做法是重连后重订阅,并用轮询兜底核对最新高度,两套机制互为校验。

第二,重组会回撤已经推过的事实。newHeads 事件只告诉你有区块头出现,不代表它永久入链;一旦链尖分叉,旧头部对应的区块可能不再是最长链的一部分,基于它触发的提醒、计数、状态机都可能需要回滚修正。logs 同理:事件属于某个区块,区块被换掉,事件也要重新核对。把重组当作小概率理论问题,等于把整个监控建立在沙滩上——至少要在关键判断处确认区块确认数或最终性层,而不是首见事件就下结论。

给使用者的检查清单

即使你不写代码,这些判断也适用:面板没通知,先问一句它走的是哪种通道;地址监控应用在网络断开恢复后不提醒,通常是重连后没重新订阅,杀掉重启往往能恢复;网页上的确认数缓慢,多半是索引端还在处理,与推送模式无关;重组窗口内看到的任何已到账提示,都要以最终确认数为准再采信。同名资产在不同网络上的事件不能混用同一个过滤器,跨链监控务必按链 ID 分开建立订阅。

最后给一条成本直觉:轮询的费用花在自己和端点的额度上,订阅的费用花在连接的维护上。个人自用低频监控,轮询足够且最省心;需要秒级响应的关键地址,才值得维护订阅通道加自动重连的复杂度。先按业务对延迟的真实要求选模式,再谈优化,是这类监控系统少返工的关键。

风险提示:本文解释链上数据获取机制,不构成投资建议;对大额到账判断,请以多条链上证据交叉核验为准。