本文承接交易所到券商的上游链路,继续沿着券商内部行情总线、分发节点、UDP 组播、A/B 交换网络和物理链路,一直讲到行情以太网帧到达量化机构 Colo 服务器的网卡端口。本文仍不进入行情程序内部,不讨论用户态收包、消息合并、协议解码和订单簿构建。
本篇范围:券商行情接入节点的输出,直到服务器物理网卡收到以太网帧。网卡 RX Queue、内核旁路、Channel/Seq 合并、补包、解码和订单簿处理留到后续文章。
1. 券商为什么还要重新分发行情
交易所提供的行情接口主要服务于市场参与者或信息服务商的接入系统。券商收到行情后,机房中可能有多个内部系统和多个 Colo 客户需要消费同一份数据。如果每台服务器都直接与交易所建立独立会话,会带来权限、连接数量、运维和恢复上的复杂性。
因此,券商通常会建设内部行情分发层:
交易所行情接入
→ 券商内部接收与校验
→ 内部标准化或封装
→ A/B 分发节点
→ UDP 组播网络
→ 多台 Colo 服务器这个分发层解决的是“一份上游行情如何低延迟地送给很多接收者”,不等同于量化机构自己的行情处理程序。
2. 券商可能发送什么数据
券商内部转发并不只有一种方式。量化机构必须先确认收到的究竟是哪一种。
2.1 交易所原始消息透传
券商传输包头
+ 交易所原始消息特点:
- 原始字段保留较完整;
- 量化机构需要自行适配不同交易所协议;
- 外层券商包序号和内层交易所业务序号必须区分;
- 协议升级需要量化机构同步适配。
2.2 券商统一格式
交易所协议
→ 券商标准化结构
→ 内部组播特点:
- 上交所、深交所等可以使用统一字段;
- 接入成本更低;
- 需要确认是否丢失交易所原始字段;
- Channel、Seq、订单编号和时间戳可能被重写;
- 字段名称相同不代表语义与交易所原始字段相同。
2.3 券商构建后输出盘口
逐笔消息
→ 券商订单簿
→ 十档快照或盘口增量特点:
- 使用简单;
- 接收端不必自行维护全部逐笔状态;
- 无法还原被聚合掉的订单级信息;
- 本地模型依赖券商订单簿算法和恢复状态;
- 不适合需要订单编号、排队位置或精细订单流的策略。
三种产品不能仅凭“都是 Level-2”混为一谈。
3. UDP组播为什么适合机房行情分发
UDP 组播允许发送节点向一个组播地址发送一份数据,由交换机复制到所有加入该组播组的端口。
如果使用大量独立 TCP 连接,发送节点需要维护每个客户连接,并受到慢接收者、重传和发送缓存的影响。组播更适合高频行情的一对多分发:
- 发送端只需发送一份;
- 交换网络完成复制;
- 某个接收者变慢不会直接阻塞其他接收者;
- 后续包不会因为一个包丢失而等待传输层重传。
代价是 UDP 本身不保证:
- 一定送达;
- 按顺序到达;
- 不重复;
- 自动重传;
- 接收者状态可见。
因此,完整性检查和恢复必须由上层协议、双路网络或恢复服务完成。具体算法属于后续行情接收程序文章,本篇只讨论这些机制依赖的网络前提。
4. 一个典型的券商UDP包
券商内部 UDP 数据报可能包含外层传输头和一条或多条业务消息:
Ethernet Header
IP Header
UDP Header
Broker Packet Header
source_id
path_id
packet_channel
packet_sequence
send_timestamp
message_count
Market Message 1
Market Message 2
...需要特别区分:
- 外层 PacketSeq:描述券商发送的 UDP 包;
- 内层业务 Channel/Seq:描述行情业务流中的消息顺序。
一条 UDP 包可能包含多条业务消息;丢失一个 UDP 包,可能同时丢失多条业务记录。反过来,外层 PacketSeq 连续也不能证明内层业务消息一定完整,因为上游接入系统可能在封包前已经缺失数据。
5. A/B双路到底是什么
A/B 双路的目标通常包括:
- 降低单链路故障影响;
- 一路丢包时从另一路获得同一业务消息;
- 选择先到的一路以降低尾部延迟;
- 监控两个路径的延迟和完整性差异。
但是,“A/B”只是标签,不能自动证明两路真正独立。
5.1 四个不同概念
| 概念 | 含义 | 能解决的问题 |
|---|---|---|
| 双端口 | 一张网卡的两个物理端口 | 单根线缆或单端口问题 |
| 双网卡 | 一台服务器的两张网卡 | 单网卡、驱动或 PCIe 卡故障的一部分风险 |
| 双网络路径 | 不同交换机、线缆和端口 | 网络设备与物理链路故障 |
| 双行情源 | 独立上游接入节点或供应商 | 上游数据源和接入程序故障 |
双网卡不等于双源,双交换机也不等于上游数据独立。
5.2 常见伪双路
这套结构可以防止部分交换机、线缆和网卡故障,但如果上游接入程序遗漏某条消息,A/B 会同时缺失。
5.3 更完整的双路
即使如此,仍需继续确认 UA 和 UB 是否共享交易所出口、运营商线路、时钟源、电源或机房设备。冗余设计的核心是识别共同故障域,而不是统计设备数量。
6. 同源双路和异源多源
6.1 同源双路
两路承载相同的逻辑业务事件,可能只是物理路径或发送节点不同。理想情况下,内层业务标识能够对应同一事件,但外层 UDP 包序号、封包数量和发送时间可以不同。
同源双路适合在接收程序前端做去重和互补,但前提是券商明确说明两路属于同一个业务序号域。
6.2 异源多源
例如:
- 交易所直连源;
- 券商 A 的标准化源;
- 券商 B 的原始透传源;
- 第三方十档快照源。
这些源的 Channel、Seq、封包方式和消息粒度通常不能直接比较。正确做法往往是独立接收、独立构建状态,再进行校验或整体切换,而不是把不同序号域的消息随意拼接。
本篇不展开多源订单簿合并,只强调:在网络设计阶段必须给每个源和路径建立明确身份,不能让接收程序只看到两个无法区分的 UDP Socket。
7. VLAN和组播隔离
VLAN 可以理解为交换网络中的逻辑隔离区域。券商可能按市场、行情产品、客户或 A/B 路划分 VLAN。
需要确认:
- A/B 是否属于不同 VLAN;
- 组播地址和 UDP 端口是否可能重复;
- 服务器接口是否加入正确 VLAN;
- 网络变更是否会把 A/B 接到同一广播域;
- 管理流量是否与行情流量共用网络。
行情网络应尽量避免承载日志上传、数据库同步、部署、监控大流量等非关键业务。否则这些流量可能在交换机端口或服务器网卡前与行情争抢带宽和缓存。
8. IGMP和组播转发表
IGMP 是主机声明“我要接收某个组播组”的协议。交换机通过 IGMP Snooping 观察成员关系,只把组播数据发送到需要的端口。
8.1 正常过程
服务器加入组播组
→ 接入交换机学习成员关系
→ 组播转发表记录目标端口
→ 行情只复制到对应服务器8.2 常见问题
- 服务器没有成功加入组播;
- IGMP Querier 配置异常;
- 成员关系超时;
- 交换机重启后未恢复转发表;
- 组播被泛洪到所有端口;
- A/B 组播组配置反向;
- 源特定组播的源地址不匹配;
- ACL 或安全策略阻断组播控制报文。
8.3 解决方向
- 固化组播地址、端口、源地址和 VLAN 清单;
- 盘前检查服务器成员关系;
- 检查交换机组播转发表;
- 监控组播加入和离开事件;
- 模拟交换机重启和接口抖动;
- 对网络配置变更执行前后消息连续性对比。
9. 交换机为什么会丢包
即使端口带宽显示远未占满,交换机仍可能因为微突发丢包。
9.1 什么是微突发
行情并不是均匀到达。开盘、收盘或价格快速变化时,大量委托、撤单和成交可能在极短时间内集中发布。
平均带宽不高
+ 瞬时大量小包到达
→ 出口队列短时间填满
→ 交换机缓存溢出
→ 部分包被丢弃对行情网络,包速率 PPS 和瞬时队列占用经常比分钟平均带宽更重要。
9.2 交换机选型和配置关注点
- 小包转发性能;
- 端口和交换结构是否无阻塞;
- 出口缓冲和队列策略;
- 组播复制能力;
- 硬件时间戳和 PTP 支持;
- 端口丢弃、拥塞和错误计数;
- 配置变更和升级方式;
- A/B 是否使用独立设备和独立上联。
不应只根据交换机总背板带宽判断行情网络是否安全。
10. MTU和IP分片
MTU 表示链路允许承载的最大网络包尺寸。如果券商 UDP 数据报超过某段链路的 MTU,可能发生 IP 分片。
分片带来的风险:
- 任意一个分片丢失,整个 UDP 数据报都无法恢复;
- 分片重组增加接收路径复杂度;
- 中间设备可能对分片处理不一致;
- 抓包和故障定位更加困难。
需要统一确认:
- 发送节点 MTU;
- 所有交换端口和 VLAN 的 MTU;
- 服务器网卡 MTU;
- 最大 UDP 数据报长度;
- 是否允许 Jumbo Frame;
- 是否明确禁止 IP 分片。
低延迟系统不应默认“大 MTU 一定更快”或“小包一定不会分片”,而应以实际封包大小和全链路一致配置为准。
11. 光纤、光模块和线缆
行情进入服务器前的最后一段仍然是物理链路。常见连接介质包括光纤、DAC 和 AOC。
11.1 需要匹配的因素
- 端口速率;
- SFP、SFP28、SFP56、QSFP 等接口形态;
- 单模或多模;
- 波长和传输距离;
- 交换机与网卡兼容性;
- 厂商固件对白名单的要求;
- FEC 等链路参数。
11.2 常见故障
- 光功率异常;
- 接头污染或松动;
- 光纤弯折;
- 模块温度过高;
- CRC 或帧错误;
- 链路频繁上下线;
- 端口协商到错误速率;
- A/B 两路经过同一桥架或配线设备。
11.3 运维措施
- 建立经过验证的模块和线缆清单;
- 监控光功率、温度和误码;
- 保存端口上下线事件;
- A/B 使用独立端口、模块、线缆和路径;
- 准备已验证的冷备件;
- 网络变更后执行原始包数量与延迟对比。
12. 行情到达服务器网卡时发生了什么
到达本文终点时,链路发生的是:
交换机发出以太网帧
→ 光模块或线缆传输
→ 网卡物理层接收信号
→ 网卡完成基础帧校验此时行情还没有:
- 被应用程序读取;
- 被解析成委托或成交;
- 被按 Channel 和 Seq 排序;
- 被 A/B 合并;
- 被用于构建订单簿。
因此,“交换机端口显示已发送”和“行情程序已经收到”之间仍然隔着网卡、PCIe、内存、驱动、接收队列和软件路径。这些内容会在后续文章讨论。
13. 服务器前的故障如何定位
假设行情程序最终报告业务序号缺口,排查不能直接从程序代码开始。
13.1 只有A路缺失
优先关注:
- 分发节点 A;
- 交换网络 A;
- A 路组播配置;
- A 路光链路;
- 网卡 A 前的物理端口。
13.2 A/B同时缺失相同业务消息
优先关注:
- 两路共同上游;
- 内部标准化或封装程序;
- 共享行情总线;
- 交易所到券商的接入链路;
- 两路是否其实属于同一个数据副本。
13.3 外层UDP包连续但业务消息缺失
说明问题可能发生在 UDP 封包之前,或供应商对消息做了过滤、转换和重新编号。不能只监控 PacketSeq 而忽略业务层身份。
14. 全链路监控指标
14.1 分发节点
- 每个行情产品的输入和输出消息数;
- 每秒包数和字节数;
- 封包等待时间;
- 发送队列深度;
- PacketSeq;
- A/B 输出差异;
- 进程 CPU 和内存压力。
14.2 交换网络
- 入口和出口包数;
- 端口丢弃;
- 队列拥塞;
- CRC 和帧错误;
- 组播成员数量;
- 链路上下线;
- PTP 状态;
- 峰值 PPS。
14.3 物理链路
- 光功率;
- 模块温度;
- FEC 或误码计数;
- 端口速率;
- 模块和线缆序列号;
- 变更时间和操作记录。
14.4 A/B比较
- 两路包数差异;
- 两路到达延迟差;
- 单路静默时间;
- 同一业务事件的字段差异;
- 两路共同缺口;
- 两路同时发生链路错误的频率。
15. 盘前、盘中和盘后流程
15.1 盘前
- 检查分发节点 A/B;
- 检查组播地址、端口、源地址和 VLAN;
- 检查 IGMP 成员关系;
- 检查交换机端口和光链路;
- 检查服务器两张网卡端口状态;
- 比较 A/B 测试消息;
- 检查时间同步;
- 确认原始包录制和监控已经启动。
15.2 盘中
- 单路断流时继续观察备用路并告警;
- 两路同时异常时将行情源标记为不可用;
- 交换机丢包或光链路误码时快速定位端口;
- 配置变更必须审计;
- 不以“还有 UDP 包到达”代替业务完整性判断。
15.3 盘后
- 统计 A/B 包数、缺口、重复和延迟;
- 对比交换机与服务器端计数;
- 复盘所有端口错误和链路抖动;
- 保存网络配置快照;
- 对异常时间段进行原始包重放;
- 更新故障域和依赖关系图。
16. 故障注入计划
生产前至少应验证:
- 断开 A 路物理链路;
- 断开 B 路物理链路;
- 重启一台接入交换机;
- 清除组播成员关系;
- 模拟端口微突发;
- 模拟单路丢包、重复和延迟;
- 模拟两路到达顺序反转;
- 模拟分发节点停止发送;
- 模拟 A/B 同时缺少同一业务消息;
- 验证每种故障能否被正确归因和告警。
故障注入的目的不是证明系统“永远不出错”,而是确认:发生错误时,系统知道影响了哪条路径、哪些行情产品和哪些服务器。
17. 关键设计取舍
17.1 一张双口卡还是两张独立卡
一张双口卡成本更低、布线简单,但两个端口共享网卡芯片、PCIe 插槽、固件和供电。若目标是降低单卡故障风险,A/B 应优先使用两张独立物理卡。
17.2 双路抢先还是严格主备
双路抢先可以降低到达延迟并利用另一条路补齐单路丢包,但接收侧合并逻辑更复杂。严格主备实现简单,却不能同时利用两条路的低延迟优势。该选择属于网卡之后的行情接收程序设计,本文只要求网络层保留可靠的路径标识和独立性。
17.3 共享网络还是专用行情网络
共享网络利用率高,但非行情流量可能产生拥塞和微突发。高频场景通常更倾向专用 VLAN、专用交换端口甚至独立交换网络,用资源换取更稳定的延迟和故障边界。
18. 仍需向券商确认的问题
- 券商输出的是原始透传、统一格式还是盘口结果;
- 外层 PacketSeq 和内层业务 Seq 分别如何定义;
- A/B 是否属于同一个业务序号域;
- A/B 分发节点是否共享上游接入程序;
- 是否提供独立恢复服务;
- 每个 UDP 包最多包含多少业务消息;
- 最大包长和 MTU 要求;
- 组播地址、端口、源地址和 VLAN;
- 交换机和物理路径是否真正独立;
- PTP 时间由谁提供;
- Colo 客户能否获得交换机端口和分发节点指标。
这些信息在没有正式接口规范和机房拓扑前都属于“未确认”。
19. 下一篇:服务器网卡怎么选
下一篇将把终点放在服务器硬件入口,讨论:
- Solarflare、NVIDIA ConnectX 和 FPGA 定制卡的定位差异;
- 端口速率、PPS、尾部延迟和硬件时间戳;
- 两张独立网卡与一张双口网卡的取舍;
- PCIe、NUMA 和固件版本为什么需要纳入选型;
- 为什么 FPGA 不是简单的高配网卡;
- 如何设计可复现的网卡验收测试。
本文仅为个人学习笔记和系统架构设计整理,不构成任何投资建议或交易建议。高频量化交易系统涉及市场风险、技术风险、合规风险和运维风险,任何实盘部署都应经过充分测试、独立验证和风险评估。