我们的目标是以Spring Cloud为基础,从零开始搭建一个7x24小时运行的证券交易所。
除了Spring Cloud外,通常项目还需要依赖数据库、消息系统、缓存等各种组件。我们选择组件的原则是通用性高,使用广泛,因此,数据库选择MySQL 8.x,消息系统选择Kafka 3.x,缓存系统选择Redis 6.x。
由于我们的项目是一个7x24小时运行的证券交易系统,因此,我们简单分析一下业务系统的特点:
为了简化设计,我们把项目需求限定如下:
项目名称暂定为Warp Exchange,采用GPL v3授权协议。项目最终完成后,效果如下:
对一个系统来说,建立一个简单可靠的模型,不但能大大简化系统的设计,而且能以较少的代码实现一个稳定运行的系统,最大限度地减少各种难以预测的错误。
我们来看证券交易系统的业务模型。
对于证券交易系统来说,其输入是所有交易员发送的买卖订单。系统接收到订单后,内部经过定序,再由撮合引擎进行买卖撮合,最后对成交的订单进行清算,买卖双方交换Base和Quote资产,即完成了交易。
在撮合成交的过程中,系统还需要根据成交价格、成交数量以及成交时间,对成交数据进行聚合,以便交易员能直观地以K线图的方式看到历史交易数据,因此,行情系统也是证券交易系统的一部分。此外,推送系统负责将行情、订单成交等事件推送给客户端。
最后,证券交易系统还需要给交易员提供一个操作界面,通常是Web或手机App。UI系统将在内部调用API,因此,API才是整个系统下单和撤单的唯一入口。
整个系统从逻辑上可以划分为如下模块:
以上各模块关系如下:
query
┌───────────────────────────┐
│ │
│ ▼
┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐
│ Client │──▶│ API │──▶│Sequencer│──▶│ Engine │
└─────────┘ └─────────┘ └─────────┘ └─────────┘
▲ │
│ │
┌─────────┐ ┌─────────┐ │
│ Browser │──▶│ UI │ │
└─────────┘ └─────────┘ │
▲ ▼
│ ┌─────────┐ ┌─────────┐ ┌─────────┐
└────────│WebSocket│◀──│ Push │◀──│Quotation│
└─────────┘ └─────────┘ └─────────┘
其中,交易引擎作为最核心的模块,我们需要仔细考虑如何设计一个简单可靠,且模块化程度较高的子系统。对证券交易系统来说,交易引擎内部可划分为:
交易引擎是一个以事件驱动为核心的系统,它的输入是定序后的一个个事件,输出则是撮合结果、市场行情等数据。交易引擎内部各模块关系如下:
┌ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┐
┌─────────┐ ┌─────────┐
──┼─▶│ Order │───▶│ Match │ │
└─────────┘ └─────────┘
│ │ │ │
│ │
│ ▼ ▼ │
┌─────────┐ ┌─────────┐
│ │ Asset │◀───│Clearing │ │
└─────────┘ └─────────┘
└ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┘
经过这样的模块化设计,一个证券交易系统就具备了基本的雏型。