交易系统核心链路:订单接收与解码、风控检查、订单路由、行情处理、撮合引擎

大家好,我是你们的老朋友。今天咱们聊聊交易系统的核心链路。

说白了,一条订单从客户端发出来,到最终成交或被拒绝,中间要经过好几个关键环节。我这些年拆过不少系统,发现很多性能问题都出在这些链路上。你想想看,如果某个环节慢了,整个系统的吞吐量就上不去。

嗯,咱们一个一个来看。

1. 订单接收与解码

这是第一道关卡。客户端把订单发过来,系统得先收下来,然后解析成内部能理解的数据结构。

接收环节,我个人习惯用非阻塞 I/O 模型。为什么?因为阻塞模型下,一个连接卡住了,后面的都得等着。我在项目中遇到过,某次线上事故就是因为接收线程被一个慢客户端拖死,导致大量订单堆积。

解码环节,说白了就是把二进制流变成订单对象。这里有个坑:不要用通用 JSON 解析器。通用解析器虽然方便,但性能差得远。我建议自己写定长字段解析器,或者用 Protobuf 这类高性能序列化方案。

核心要点:

  • 接收用 Reactor 模式,一个线程管多个连接
  • 解码用零拷贝技术,减少内存复制
  • 预分配对象池,避免频繁 GC

避坑指南:我曾经见过一个团队,解码时用了正则表达式来提取字段。结果压测时 CPU 直接飙到 90% 以上。后来改成手工解析,CPU 降到 20%。记住:正则表达式是性能杀手

2. 风控检查

订单解码完了,接下来就是风控。这一步不能省,但也不能太慢。

风控检查通常包括:

  • 账户余额检查
  • 持仓限制检查
  • 价格偏离检查
  • 频率限制检查

我建议把风控规则分成两类:静态规则动态规则。静态规则(比如账户是否存在)可以缓存起来,不用每次都查数据库。动态规则(比如价格偏离)则需要实时计算。

这里有个技巧:把风控检查做成流水线。先做快的检查(比如频率限制),再做慢的检查(比如数据库查询)。这样大部分订单在第一步就被过滤掉了,后面的压力就小了。

注意:风控检查不能完全异步。有些规则必须同步执行,否则会出现「先成交后风控」的尴尬局面。我见过一个系统,因为异步风控导致用户透支交易,最后赔了不少钱。

3. 订单路由

风控过了,订单该往哪送?这就涉及到路由了。

订单路由的核心是找到最优的撮合引擎。比如,一个 BTC/USDT 的买单,应该送到哪个撮合引擎去处理?

我个人习惯用一致性哈希来做路由。为什么?因为这样同一个交易对的订单总能落到同一个引擎上,避免了跨引擎的同步问题。

路由表要支持动态更新。我在项目中遇到过,某个撮合引擎挂了,路由表没及时更新,结果订单全打到了死节点上。嗯,那次事故让我养成了「路由表必须带健康检查」的习惯。

路由策略对比:

策略 优点 缺点
轮询 实现简单 无法保证同一交易对落到同一引擎
一致性哈希 扩展性好,节点变化影响小 实现稍复杂
最小连接数 负载均衡效果好 需要实时统计连接数

4. 行情处理

行情处理是交易系统的「眼睛」。没有行情,撮合引擎就是瞎子。

行情数据通常包括:

  • 深度数据(买卖盘口)
  • 成交数据(最近成交记录)
  • Ticker 数据(最新价、涨跌幅等)

行情处理的难点在于数据量大、更新频率高。一个活跃的交易对,每秒可能有几千次深度更新。如果处理不当,CPU 很快就满了。

我建议用增量更新代替全量推送。比如,深度变了,只推送变化的那几档,而不是整个深度数据。这样网络带宽和 CPU 都能省不少。

个人经验:我曾经优化过一个行情系统,把全量推送改成增量更新后,CPU 使用率从 80% 降到了 30%。而且客户端体验反而更好了,因为数据更新更及时了。

5. 撮合引擎

终于到了核心中的核心——撮合引擎。

撮合引擎的任务很简单:把买单和卖单匹配起来。但实现起来,细节多得很。

撮合引擎的核心数据结构是订单簿。买单按价格从高到低排列,卖单按价格从低到高排列。每次来一个新订单,就从订单簿的另一边找匹配的订单。

我见过很多撮合引擎的实现,有的用红黑树,有的用跳表,有的直接用数组。我个人习惯用跳表。为什么?因为跳表的插入和删除都是 O(log n),而且实现起来比红黑树简单,不容易出 bug。

撮合引擎的性能瓶颈通常不在算法上,而在锁竞争上。如果多个线程同时操作订单簿,锁的争用会非常严重。

锁优化策略:

  • 使用读写锁:读多写少时性能好
  • 使用无锁数据结构:比如 CAS 操作
  • 使用分片锁:把订单簿分成多个区域,每个区域一把锁

注意:无锁编程虽然性能好,但调试起来非常痛苦。我建议除非你经验丰富,否则还是用读写锁加分片的方式更稳妥。我曾经花了两周时间调试一个无锁队列的 bug,最后发现是内存屏障的问题。嗯,那两周我头发都白了不少。

核心链路流程图

下面这张图展示了订单从接收到成交的完整流程。我画得比较简洁,但每个环节的要点都在里面了。

交易系统核心链路流程图 订单接收 解码 风控检查 订单路由 撮合引擎 非阻塞I/O 零拷贝、对象池 静态+动态规则 一致性哈希 跳表、无锁 每个环节都可能成为性能瓶颈,需要针对性优化

好了,核心链路就讲到这里。每个环节都有它的门道,也都有它的坑。我在后面几章会深入讲每个环节的优化技巧,到时候咱们再细聊。

记住一句话:性能优化不是一蹴而就的,而是不断发现瓶颈、解决瓶颈的过程。你想想看,是不是这个理?