3. 错序缺帧的检测与定位方法
逐笔回放出现“画面跳变、成交明细对不上、K线缺口”时,根因往往不是回放引擎本身,而是数据在采集、传输或落盘环节发生了错序或缺帧。本节聚焦三类可落地的检测手段——序列号、时间戳、快照比对,并给出日志与监控指标的设计方法,目标是让问题从“用户反馈”变成“系统自动报警并定位到具体通道与时间段”。
一、三类检测手段的定位能力差异
三种手段并非互相替代,而是覆盖不同的故障面。序列号检测擅长发现“丢了哪一帧”,时间戳检测擅长发现“顺序乱了、延迟大了”,快照比对擅长发现“内容错了但序号连续”的隐蔽问题。实际排障中通常组合使用。
二、序列号检测:最直接的缺帧证据
逐笔数据通常带有交易所或网关分配的递增序列号(seq)。检测逻辑很朴素:对同一通道,维护 last_seq,新帧到达时计算 delta = seq - last_seq。若 delta == 1 正常;delta > 1 说明中间缺了 delta - 1 帧;delta <= 0 则是重复或回退,属于错序。示例:某通道上一帧 seq=100238,新帧 seq=100245,则缺口为 6 帧,区间为 [100239, 100244]。
工程上要注意两点。其一,序列号可能按通道独立编号,也可能全局编号,检测前必须确认作用域,否则跨通道比较会误报。其二,网关重连后序列号可能重置,需在日志中记录 session_id,重置时清空 last_seq 并打一条 seq_reset 事件,避免把正常重置当成大规模缺帧。
三、时间戳检测:捕捉错序与延迟
时间戳检测关注两个量:单调性和滞后度。同一通道内,若后到帧的 ts 小于前一帧,即出现倒挂,说明消息在队列或网络中被乱序投递。滞后度用 recv_ts - ts 衡量,反映从产生到接收的端到端延迟。示例阈值可设为:倒挂即记 disorder 事件;recv_ts - ts > 500ms 记 slow 事件并计入 p99 延迟指标。
需要提醒的是,不同来源的时间戳精度不同(毫秒、微秒、纳秒),比较前统一到同一单位;跨主机时钟未同步时,倒挂可能是时钟偏差而非真乱序,因此建议同时记录本机接收时间,用 recv_ts 序列做二次判断。
四、快照比对:发现“序号连续但内容缺失”
有些缺帧发生在更上游——交易所推送本身就漏了,序列号在网关侧被重新连续编号,此时前两种手段都会失效。快照比对用“累计量守恒”来兜底:每隔固定周期(如 3 秒)取一次行情快照,快照中的累计成交量、累计成交额是权威值。将本周期内逐笔记录的成交量累加,与快照增量比较:
快照增量 = 本周期快照累计量 - 上周期快照累计量
逐笔累加 = Σ(本周期内各笔成交量)
差值 = 快照增量 - 逐笔累加
若 差值 > 0 → 本周期内存在未被采集到的成交(缺帧)
若 差值 < 0 → 存在重复帧或跨周期错位
示例:某标的 09:30:00 快照累计成交量 12000 手,09:30:03 快照为 12650 手,增量 650 手;而该 3 秒内逐笔累加仅 620 手,差值 30 手,说明约 30 手对应的逐笔帧缺失,定位窗口即这 3 秒。差值不为零时,应把该时间窗内的通道、seq 区间、ts 区间一并写入复核工单。
五、日志与监控指标设计
检测要可运维,必须落到结构化日志和可聚合指标上。日志建议每批(如每 100 帧或每 200ms)输出一条汇总记录,字段包括:channel、session_id、seq_start、seq_end、gap_cnt、disorder_cnt、ts_lag_max、snapshot_diff。单帧级异常另打一条明细日志,保留前后各 3 帧的 seq 与 ts,便于回放复现。
监控指标按“量、率、时延”三类组织:gap_total(累计缺口帧数)、gap_rate(缺口帧/总帧)、disorder_total、ts_lag_p99、snapshot_diff_total。告警策略建议分级:缺口大于 0 且持续 2 个周期即告警;倒挂次数 1 分钟内超过 5 次告警;快照差值绝对值超过该标的近 1 小时均量的 0.5% 触发复核。所有告警都应携带通道号与时间窗,直接指向可排查的区间,而不是只报“数据异常”。
gap_total 是否突增(缺帧),再看 disorder_total 与 ts_lag_p99(错序/延迟),最后用 snapshot_diff 兜底验证内容完整性。三者同时异常时,优先怀疑采集网关或消息队列的重试与分区策略。