3. 错序缺帧的检测与定位方法

逐笔回放出现“画面跳变、成交明细对不上、K线缺口”时,根因往往不是回放引擎本身,而是数据在采集、传输或落盘环节发生了错序或缺帧。本节聚焦三类可落地的检测手段——序列号、时间戳、快照比对,并给出日志与监控指标的设计方法,目标是让问题从“用户反馈”变成“系统自动报警并定位到具体通道与时间段”。

一、三类检测手段的定位能力差异

三种手段并非互相替代,而是覆盖不同的故障面。序列号检测擅长发现“丢了哪一帧”,时间戳检测擅长发现“顺序乱了、延迟大了”,快照比对擅长发现“内容错了但序号连续”的隐蔽问题。实际排障中通常组合使用。

逐笔数据流与三类检测点 行情源 逐笔推送 采集网关 打标/缓冲 消息队列 分区/重试 落盘存储 逐笔文件 回放 引擎 ① 序列号检测 判据:seq 连续递增,步长=1 缺帧:seq 跳变,缺口=后-前-1 错序:seq 回退或重复 定位:通道号 + 缺口区间 ② 时间戳检测 判据:ts 单调不减(同通道) 错序:ts 倒挂,Δts < 0 延迟:now - ts 超阈值 定位:倒挂点前后各 N 帧 ③ 快照比对 判据:累计成交量/额 与快照一致 缺帧:逐笔累加 < 快照增量 内容错:序号连续但数值不符 定位:快照周期内的时间窗 日志与监控指标设计 日志字段(每帧/每批) channel, seq, ts, recv_ts, gap_cnt, disorder_flag 核心指标 gap_total, disorder_total, ts_lag_p99, snapshot_diff 告警与定位 缺口>0 立即告警;倒挂>阈值 告警;快照差>0 触发复核

二、序列号检测:最直接的缺帧证据

逐笔数据通常带有交易所或网关分配的递增序列号(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 兜底验证内容完整性。三者同时异常时,优先怀疑采集网关或消息队列的重试与分区策略。