区块链交易所中心化撮合系统详解
区块链交易所中心化撮合系统详解
微信公众号:密码应用技术实战
博客园首页:https://www.cnblogs.com/informatics/
GitHub地址:https://github.com/warm3snow
🔁 系统总体架构与核心模块
交易引擎采用分层、模块化的设计,其核心目标是实现高并发、低延迟和高可靠性。整个系统从用户下单到最终成交的数据流转与核心交互逻辑,可以通过下图一览全貌:
flowchart TD
A[用户接口<br>Web/App/API] --> B[API网关<br>与负载均衡]
B --> C1[订单管理服务]
B --> C2[用户管理服务]
B --> C3[资产账户服务]
C1 --> D[消息队列<br>Kafka]
C2 --> D
C3 --> D
D --> E[订单网关]
subgraph F [交易引擎集群]
E --> G1[交易对分区1<br>USDT/BTC 引擎实例]
E --> G2[交易对分区2<br>USDT/ETH 引擎实例]
E --> G3[交易对分区N<br>...]
subgraph G1_Sub [USDT/BTC 撮合引擎]
H1[订单簿<br>买盘/卖盘]
I1[撮合算法核心]
end
subgraph G2_Sub [USDT/ETH 撮合引擎]
H2[订单簿<br>买盘/卖盘]
I2[撮合算法核心]
end
G1 --> H1
G1 --> I1
G2 --> H2
G2 --> I2
end
I1 --> J1[成交记录]
I2 --> J2[成交记录]
J1 --> K[行情引擎]
J2 --> K
K --> L1[持久化存储<br>MySQL]
K --> L2[缓存与推送<br>Redis]
L2 --> M1[WebSocket<br>实时行情推送]
L2 --> M2[前端展示<br>K线/深度图]
如上图所示,该系统主要包含以下核心模块:
- API网关与微服务层:作为系统门户,负责认证、限流、请求路由。订单、用户、资产等服务各自独立,通过Spring Cloud或Dubbo等框架协同工作。
- 订单网关:承接API网关转发的订单,进行基本合规性检查(如价格笼子),并作为消息生产者将订单发布到消息队列(如Kafka)。队列起到了削峰填谷和解耦的作用。
- 撮合引擎集群:这是最核心的部分。采用交易对分区设计,每个引擎实例专门负责一个或一组交易对(例如专设USDT/BTC和USDT/ETH引擎)。引擎核心是订单簿和撮合算法。
- 行情引擎:接收撮合引擎产生的成交记录,聚合生成K线、深度图等市场数据,并借助Redis等高速缓存推送给客户端。
⚙️ 核心组件深度解析
1. 订单簿数据结构
订单簿是记录所有待成交限价单的核心,其设计直接决定撮合效率。一个高性能的订单簿通常采用三层结构:
- 价格档位层:使用
TreeMap<BigDecimal, LinkedList<Order>>。TreeMap(红黑树实现)能按价格自动排序,买盘按价格降序,卖盘按价格升序,便于快速获取最优价格(买一/卖一)。 - 订单队列层:每个价格档位下使用
LinkedList维护订单队列,严格遵循时间优先原则,新订单尾插入。 - 订单索引层:使用
HashMap<OrderId, Order>实现订单快速查询,便于撤单操作。
2. 撮合算法与特殊订单处理流程
“价格优先、时间优先”是根本原则。其核心流程是一个循环匹配过程,直到新订单完全成交或无法继续匹配为止。市价单、冰山单等特殊订单类型在此流程中有其特定的处理逻辑。这个过程可以通过以下流程图来直观展示:
flowchart TD
A[新订单到达] --> B{订单类型判断}
B -->|市价单| C[进入独立市价单队列<br>拥有最高撮合优先级]
C --> D[立即尝试撮合]
D --> E{对手盘是否存在?}
E -->|是| F[以对手方最优价格<br>连续成交]
E -->|否| G[订单滞留或取消<br>(根据规则)]
F --> H[更新订单簿与行情]
B -->|冰山单| I[拆分为显性/隐性部分]
I --> J[显性部分按限价单规则挂单]
J --> K[监听成交回报]
K --> L{显性部分是否完全成交?}
L -->|是| M[从隐性部分释放<br>新的“冰山一角”]
L -->|否| N[等待或根据策略撤单重挂]
M --> J
B -->|普通限价单| O[进入标准撮合循环]
O --> P{检查对手盘最优价格}
P -->|可成交| Q[以对手方价格成交]
Q --> R{订单是否完全成交?}
R -->|是| H
R -->|否| P
P -->|不可成交| S[加入本方订单簿排队]
S --> H
H --> T[订单生命周期结束]
G --> T
以一个新买入订单(Bid)为例,它会与对手盘(卖盘)进行如下匹配:
- 检查对手盘:查看卖盘队列中是否存在价格 <= 此买入订单价格的卖单。
- 撮合成交:如果存在,则与价格最优(最低)的卖单进行匹配。成交价格为卖单价格(对买方更有利,实现“高价买、低价卖”的优先匹配),成交数量为两者数量的最小值。
- 更新状态:减少或移除已完全成交的订单。如果新订单仍有剩余数量,则继续循环匹配下一个最优卖单。
- 挂单:如果循环结束后,新订单仍未完全成交,或一开始就无法匹配,则将其加入买盘订单簿相应位置。
💡 关键技术与性能优化
在高频交易场景下,性能是生命线。以下是一些关键优化技术:
- 内存撮合:现代交易所已从“数据库撮合”转向内存撮合,将整个订单簿和撮合逻辑置于内存中,避免磁盘I/O瓶颈,性能提升数个数量级。
- 无锁数据结构与高性能队列:为避免线程竞争,采用
Disruptor等无锁环形队列处理订单流,实现单线程下每秒百万级订单处理。 - 多机热备份与状态机复制:为解决内存易失性,采用多机热备份。通过原子多播等技术保证多个撮合引擎副本状态一致,实现高可用性。
USDT/BTC交易对撮合
我将以USDT/BTC交易对为例,来展示用户A的市价/限价买单从提交到最终成交或挂单的订单撮合逻辑。

流程图关键步骤解析
该流程图清晰地展示了一个订单在交易所内部的完整生命周期,具体包含以下几个核心阶段:
- 订单验证与资金冻结:系统首先会检查用户A的USDT账户余额是否足够支付这笔订单。如果资金不足,订单会被立即拒绝。如果资金充足,相应的USDT金额会被冻结,确保“券款对付”,防止透支交易。
- 订单路由:验证通过的订单被订单网关接收,并根据其交易对(USDT/BTC)被路由到专门负责该交易对的独立撮合引擎实例。这使得USDT/BTC和USDT/ETH等交易对可以互不干扰地并行处理。
- 核心撮合循环:这是引擎最核心的部分,遵循“价格优先、时间优先”的原则。
- 订单类型判断:市价单的目标是立即成交,会直接匹配当前最优的卖单。限价单(60,010)则要求成交价格不能劣于其指定价格。
- 多轮匹配:引擎会持续将订单与订单簿中的对手方订单进行匹配。如流程所示,它先与卖一档的1 BTC订单成交,由于订单尚未完全成交,会继续检查下一档卖单。
- 价格判断:在匹配卖二档(60,020)时,由于60,020 > 60,010(限价),匹配过程终止。对于市价单,则会继续“吃”掉卖二档甚至更优价格的订单,直到完全成交或市场深度耗尽。
- 成交与订单簿更新:
- 完全成交:如果订单在循环中全部匹配,则订单生命结束。
- 部分成交:如果订单部分成交,剩余部分会作为一个新的限价单(价格为用户指定的60,010)被挂入买盘订单簿中排队等待。由于它的价格60,010高于当前买一价59,980,因此它会成为新的买一价。
- 行情生成与推送:每一笔成交都会被实时发送给行情引擎。行情引擎会据此更新该交易对的最新价、计算K线图等,并通过WebSocket等技术将最新的市场深度和成交信息实时推送给所有订阅的用户。
💎 总结
这套架构通过模块化拆分、交易对分区和内存撮合核心技术,构建了一个高性能、高可用的交易引擎。它以订单簿为核心数据结构,通过严格遵循价格优先、时间优先的确定性撮合算法,保证了交易的公平性和效率。同时,系统通过特殊的处理逻辑有效地支持了市价单、冰山单等高级订单类型,满足了多样化的交易需求。
希望这份整合后的详细设计说明能帮助您深入理解交易引擎的架构奥秘和核心流程。如果您对更多特定细节感兴趣,我们可以继续深入探讨。

浙公网安备 33010602011771号