第三章:系统架构总览——分层架构设计、微服务 vs 单体、高可用原则
做市商系统,说白了就是一台高速运转的印钞机——前提是你得把它造对。
我见过太多团队,一上来就撸代码,结果三个月后发现自己掉进了泥潭。为什么?因为架构没想清楚。今天这一章,咱们就把做市商系统的骨架聊透。我会从分层架构、服务选型、高可用设计三个维度展开,中间穿插一些我踩过的坑。
一、分层架构设计:接入层、业务层、数据层
我个人习惯,做任何系统都先画三层。不是老套,是管用。
做市商系统尤其如此。你想想看,行情数据每秒进来几千笔,订单要毫秒级响应,风控还得实时拦截——不分层,代码就是一锅粥。
1. 接入层:系统的脸面
接入层负责跟外界打交道。包括交易所的行情推送、订单网关、WebSocket连接管理、REST API接口。
这里有个关键点:协议转换。交易所用FIX协议,内部系统用Protobuf,中间得有个适配层。我在项目中遇到过,某次交易所升级了FIX版本,结果我们的网关没跟上,直接断连了半小时。嗯,从那以后我强制要求接入层必须支持热加载协议配置。
- 连接管理(心跳、重连、限流)
- 协议解析与序列化
- 身份认证与权限校验
- 流量整形(防止上游突发流量打垮下游)
2. 业务层:大脑所在
业务层是核心。定价引擎、订单管理、风险控制、仓位核算,全在这里。
我建议业务层一定要做无状态设计。为什么?因为只有无状态才能水平扩展。你想想看,如果每个业务实例都维护着本地订单状态,一旦宕机,那堆状态就丢了。我曾经接手过一个项目,业务层用本地HashMap存订单,每次重启都得等恢复脚本跑半小时——惨不忍睹。
业务层的典型模块:
- 定价引擎:根据市场深度、库存、波动率计算报价
- 订单路由:决定订单发往哪个交易所
- 风控模块:检查单笔限额、日内亏损、持仓集中度
- 清算对账:与交易所逐笔核对成交和资金
3. 数据层:一切的基础
数据层不只是存数据,更是数据的组织方式。
做市商系统的数据有几个特点:
- 高频写入(行情、订单、成交)
- 低延迟查询(实时仓位、风险敞口)
- 强一致性要求(资金、持仓不能错)
所以数据层不能只用一种数据库。我常用的组合是:
| 数据类型 | 存储方案 | 原因 |
|---|---|---|
| 行情快照 | Redis / 内存数据库 | 纳秒级读写,不持久化也行 |
| 订单流水 | Kafka + 时序数据库 | 高吞吐写入,按时间范围查询 |
| 资金持仓 | 关系型数据库(MySQL/PostgreSQL) | 事务支持,强一致性 |
| 历史分析 | 列式存储(ClickHouse) | 大范围聚合查询快 |
二、微服务 vs 单体架构选型
这个问题,每次跟同行聊都能吵起来。我的态度很明确:看阶段,看规模。
1. 单体架构:起步快,但别贪心
如果你团队只有三五个人,日交易量不到一万笔,单体架构完全够用。我第一个做市商项目就是单体,一个Java进程搞定所有。开发快、部署简单、调试方便。
但单体有个致命问题:故障隔离差。定价引擎挂了,整个系统都瘫。我记得有一次风控模块内存泄漏,结果订单网关也跟着挂了,交易所那边直接发了警告函。
- 团队超过10人,代码合并冲突频繁
- 某个模块需要独立扩缩容(比如行情处理需要10个实例,但风控只需要2个)
- 某个模块的故障会拖垮整个系统
2. 微服务:灵活,但别过度
微服务的好处不用我多说:独立部署、独立扩缩、技术栈灵活。但代价也很明显——分布式复杂性。
我建议做市商系统拆成这几个微服务就够了:
- 行情服务:接收、清洗、分发行情数据
- 定价服务:计算买卖报价
- 订单服务:管理订单生命周期
- 风控服务:实时风险检查
- 清算服务:对账、结算
别拆太细。我曾经见过一个团队把定价引擎拆成三个服务——计算买价、计算卖价、计算价差。结果一次行情波动,三个服务之间来回调用,延迟从50微秒飙到5毫秒。嗯,过度设计的代价。
- 初创期:单体 + 模块化设计(为后续拆分留接口)
- 成长期:按核心业务拆4-6个微服务
- 成熟期:根据性能瓶颈和团队规模精细化拆分
三、高可用设计原则
做市商系统,宕机就是亏钱。我见过最惨的一次,某团队系统宕了15分钟,结果市场剧烈波动,重新上线后持仓已经亏了200万。所以高可用不是锦上添花,是生存底线。
1. 冗余设计:别把所有鸡蛋放一个篮子
每个关键组件都要有备用。交易所连接至少两条线路,数据库做主从复制,服务实例至少两个副本。
我习惯用N+1原则:正常需要N个实例,那就部署N+1个。多出来的那个平时分担流量,故障时自动接管。
2. 优雅降级:宁可少功能,不能全挂
系统压力过大时,要有策略地放弃非核心功能。比如:
- 行情展示可以降级为只显示最新价,不显示深度图
- 历史查询可以返回缓存数据,不查数据库
- 风控可以暂时只检查最大限额,跳过复杂模型
我在项目中遇到过,某次行情数据量暴增10倍,数据库扛不住了。我们紧急降级了历史查询和报表生成,保住了核心交易链路。虽然用户看不到历史K线了,但至少还能交易。
3. 限流与熔断:保护系统不被冲垮
做市商系统最怕什么?突发流量。比如某个币种突然暴涨,所有用户同时下单,系统瞬间被打爆。
我建议在接入层做令牌桶限流,在业务层做熔断器。限流防止外部流量过大,熔断防止内部故障扩散。
// 伪代码:令牌桶限流
public class TokenBucket {
private long capacity; // 桶容量
private long tokens; // 当前令牌数
private long lastRefill; // 上次补充时间
public boolean tryAcquire() {
refill(); // 按速率补充令牌
if (tokens > 0) {
tokens--;
return true;
}
return false; // 限流了
}
}
4. 监控与告警:看不见的故障最可怕
高可用不只是架构设计,更是运维能力。我要求每个服务必须暴露以下指标:
- QPS、延迟P99、错误率
- 连接数、内存使用率、GC频率
- 订单成功率、成交延迟
告警要分级。P0级(系统不可用)直接打电话,P1级(功能受损)发短信,P2级(性能下降)发邮件。我曾经因为告警阈值设得太低,半夜被电话吵醒三次,结果发现只是网络抖动——从那以后我学乖了,告警要设置持续时间和次数。
架构总览图
下面这张图,是我做市商系统架构的核心逻辑。你可以看到三层之间如何协作,以及高可用组件如何穿插其中。
这张图里,三层之间通过消息队列和RPC通信。高可用不是某一层的任务,而是贯穿始终的设计思想。每一层都要有冗余、限流、降级和监控。
好了,这一章的内容就到这里。架构设计没有银弹,但分层、微服务、高可用这三个维度,能帮你搭建一个经得起市场考验的系统。下一章我们会深入定价引擎的设计,那是做市商系统的核心大脑。
- 分层架构:接入层管连接,业务层管逻辑,数据层管存储
- 微服务 vs 单体:看阶段选型,别为了微服务而微服务
- 高可用三件套:冗余、降级、限流熔断
- 监控告警要独立部署,别让自己变成瞎子