第一章:做市商核心系统架构
大家好,我是老张。在场外衍生品这个行当摸爬滚打了十几年,今天咱们聊聊做市商最核心的东西——系统架构。
很多人一上来就问我:“老张,做市系统到底长什么样?” 说实话,我第一次接触这个领域时也一头雾水。后来自己动手搭过几套系统,踩过不少坑,才慢慢理清了脉络。
今天这一章,我就把做市商核心系统的分层架构、低延迟设计原则、高可用与灾备方案,掰开了揉碎了讲给你听。
一、交易系统分层架构
做市商系统,说白了就是一台高速运转的“印钞机”。但它不是乱转的,得有清晰的层次。我个人习惯把系统分成四层:接入层、逻辑层、风控层、清算层。
为什么要分层?你想想看,如果所有代码揉在一起,改个风控规则得动交易逻辑,改个接口得动清算模块,那系统就成了一团乱麻。我在项目中见过这样的“屎山”,维护成本高得吓人。
核心原则:每一层只做自己的事,层与层之间通过标准接口通信。
1.1 接入层
接入层是系统的“门面”。它负责跟外部打交道——交易所、客户、数据源等等。
具体来说,接入层要做这些事:
- 协议转换:把FIX、REST、WebSocket等不同协议转成内部统一格式
- 会话管理:维护连接状态,处理心跳、重连
- 流量控制:防止上游突发流量打垮下游
- 数据校验:检查报文格式、必填字段
我记得有一次,某个交易所突然改了FIX标签定义,我们的接入层没做兼容处理,结果整个系统瘫痪了半小时。从那以后,我要求接入层必须做协议版本检测和自动适配。
小技巧:接入层尽量用无状态设计,方便水平扩展。我习惯用Nginx做前置负载均衡,后面挂多个接入节点。
1.2 逻辑层
逻辑层是系统的“大脑”。所有业务决策都在这里完成。
逻辑层包含的核心模块:
- 订单管理:订单生命周期管理、状态机
- 定价引擎:根据市场数据计算报价
- 策略执行:执行做市策略、对冲逻辑
- 风险管理:实时监控敞口、希腊字母
这里有个坑——逻辑层千万别做太重。我曾经把一个复杂的蒙特卡洛模拟直接塞进逻辑层,结果延迟飙到毫秒级,直接被客户投诉。后来我把计算密集型任务剥离到独立的计算集群,逻辑层只做决策和调度。
注意:逻辑层是单点故障的高发区。一定要做多活部署,并且保证状态一致性。
1.3 风控层
风控层是系统的“刹车”。没有它,再好的策略也会翻车。
风控层主要做三件事:
- 事前风控:检查订单是否超限、是否违反规则
- 事中风控:实时监控持仓、盈亏、保证金
- 事后风控:生成风控报告、压力测试
我见过最惨的一次,某家做市商因为风控层没做限价检查,一个错误报价导致几千万的损失。嗯,从那以后,我坚持风控层必须独立部署,并且有独立的熔断机制。
关键点:风控层不能依赖逻辑层的判断。即使逻辑层发疯,风控层也要能拦住。
1.4 清算层
清算层是系统的“账本”。所有交易最终都要落到清算层。
清算层负责:
- 交易确认:与对手方核对交易细节
- 资金结算:计算应收应付、保证金
- 持仓管理:维护最终持仓、损益
- 报表生成:日终报表、监管报送
清算层对准确性要求极高,但对延迟要求不高。我一般用关系型数据库(比如PostgreSQL)做清算层存储,配合消息队列做异步处理。
二、低延迟架构设计原则
做市商拼的是什么?说白了就是速度。谁先报价,谁就能抢到单子。
低延迟设计有几个核心原则:
2.1 减少网络跳数
每多一次网络传输,就多几十微秒的延迟。我建议:
- 把交易服务器放在交易所机房(co-location)
- 使用低延迟交换机(比如Mellanox)
- 避免跨机房调用
2.2 避免锁竞争
锁是延迟的杀手。我见过一个系统,因为用了全局锁,延迟从10微秒飙到100微秒。
解决方案:
- 使用无锁数据结构(比如Disruptor)
- 每个线程独立处理自己的数据
- 用原子操作代替锁
2.3 减少内存分配
内存分配和垃圾回收会带来不可预测的延迟。在C++里,我习惯用对象池和预分配内存。
// 对象池示例
template<typename T>
class ObjectPool {
std::vector<T*> pool;
std::atomic<int> index;
public:
T* acquire() {
return pool[index++];
}
void release(T* obj) {
// 不真正释放,只是标记可用
}
};
2.4 使用高性能序列化
序列化/反序列化也是延迟大户。我推荐使用FlatBuffers或Cap'n Proto,而不是JSON或XML。
经验之谈:在延迟敏感路径上,尽量用二进制协议。我曾经把一个系统从JSON改成FlatBuffers,延迟降低了60%。
三、系统高可用与灾备方案
做市系统不能停。停了就是钱。
3.1 高可用设计
高可用的核心是消除单点故障。我常用的方案:
- 主备切换:一主一备,主节点挂了自动切换
- 多活部署:多个节点同时提供服务
- 负载均衡:用LVS或Nginx做流量分发
这里有个细节——主备切换时,状态同步怎么做?我建议用RAFT协议做共识,保证数据一致性。
3.2 灾备方案
灾备比高可用更进一步。它要应对机房级甚至城市级的故障。
常见的灾备等级:
| 等级 | 描述 | RTO | RPO |
|---|---|---|---|
| L0 | 无灾备 | 数小时 | 数小时 |
| L1 | 冷备 | 1-2小时 | 30分钟 |
| L2 | 温备 | 15分钟 | 5分钟 |
| L3 | 热备 | 1分钟 | 秒级 |
我个人建议做市商至少做到L2级别。L3成本太高,除非你的业务量特别大。
避坑指南:我曾经做过一个灾备方案,平时测试一切正常。结果真出故障时,发现备机上的数据落后了10分钟。原因?主备之间的同步链路带宽不够。所以,灾备方案一定要做压力测试,模拟真实流量。
四、系统架构总览
说了这么多,咱们用一张图来总结一下做市商核心系统的架构:
这张图展示了数据从接入层流入,经过逻辑层处理,风控层把关,最后到清算层落地的完整流程。每一层都独立部署,通过标准接口通信。
五、总结
做市商系统架构,说白了就是四个字:分层、解耦。接入层管通信,逻辑层管决策,风控层管安全,清算层管账本。每一层做好自己的事,系统才能稳定高效。
低延迟设计不是炫技,而是实实在在的竞争力。减少网络跳数、避免锁竞争、减少内存分配——这些原则每一条都是用真金白银换来的教训。
高可用和灾备,是系统的最后一道防线。别等到出事了才想起来做,那时候就晚了。
好了,这一章就到这里。下一章咱们聊聊定价引擎的具体实现,包括蒙特卡洛模拟和有限差分法的实战应用。