美股有三个交易时段,分别是:盘前、盘中、盘后;接口推送数据还是数值增量的逻辑(尽可能的节约带宽),仅在第一次发送全量,第二次开始所有字段都是增量推送逻辑。
为什么不用最优方案?牵扯到不同项目组,有些都已经上线多年。我方属于新对接,所以只能尽量兼容。
一系列问题
单从摘要上看,可能还觉得没什么问题,问题带入组内的系统架构,带出来一系列问题。刚处理上一个问题,又遇到了新的问题,这个问题是由于之前的问题引起的。
无法识别交易时段
已知盘中阶段定义为在 protobuf
中定义为 0,但是在收到数据的时候由于是增量推送,业务方无法有效识别这个零
是默认值,还是真实的业务值。
通俗理解:每次收到 0,无法判断这个 0 是新行情设置的值,还是 protobuf 的默认值
引入 optional
Since protobuf release 3.15, proto3 supports using the optional keyword (just as in proto2) to give a scalar field presence information
组内的通讯协议是基于 protobuf
的,但是由于历史原因,选择的版本比较老,并没支持 optional
关键字。懂的都理解,由于从底层开始引入 protobuf
,项目底层通过静态库的方式发布,导致整个编译链路都需要升级,这个成本是非常高的。
gcc 版本问题
好不容易想了方案,底层发布两个不同的版本,尽可能的控制 protobuf
新版本的编译依赖传播。但是在编译的时候,发现 gcc
版本太低,不支持 protobuf
的新特性。
组内常用的服务器类型:centos7、centos8。centos7 默认的 gcc
版本是 4.8,centos8 默认的 gcc
版本是 8.3。由于 protobuf
的新特性需要 gcc
版本在 7.4 以上,所以 centos7 无法支持。
最后折腾一圈,相关服务的部署、编译服务器都挪到 centos8 上,解决了这个问题。
合理的枚举
回顾整个问题,其实有一个更简单、高效的解决方案:调整枚举的定义,从 1 开始编号,而不是从 0 开始。这样就能有效区分默认值和业务值,避免上述一系列麻烦。
为什么从 1 开始更合理?
在 protobuf
中,枚举类型的默认值固定为 0。如果我们将有意义的业务值定义为 0(比如“盘中”),在增量推送时,业务方无法判断收到的 0 是业务值还是未设置的默认值。而如果将枚举从 1 开始定义,0 可以保留为一个无意义的默认值或“未知”状态,问题迎刃而解。
建议的实践:
在设计 protobuf 枚举时,始终将 0 定义为无意义的默认值(如 UNKNOWN
或 RESERVED
)。
将实际业务值从 1 开始分配,确保与默认值 0 区分开。
通过这一小调整,我们不仅解决了交易时段识别的问题,还为未来的协议设计提供了一个宝贵的经验教训。