
1) 【一句话结论】在期货交易系统中,选择消息队列时需结合持久化存储(确保消息不丢失)、分区/全局顺序保证(确保处理顺序正确)、基于业务标识的路由策略(确保消息分发到正确节点),通过设计订单消息的存储与路由逻辑,确保订单消息在撮合前不丢失且处理顺序正确。
2) 【原理/概念讲解】
消息持久化是指消息被写入磁盘或持久化存储(如Kafka的日志、RocketMQ的存储文件),避免系统故障(断电、进程崩溃)导致消息丢失,类比“快递公司把包裹存入仓库,即使仓库断电,包裹也不会丢失”。
顺序保证分为两类:
order:交易所ID:用户ID,确保每个交易所的订单由对应节点处理。3) 【对比与适用场景】
| 消息队列 | 持久化机制 | 顺序保证 | 适用场景 | 注意点 |
|---|---|---|---|---|
| RabbitMQ | 磁盘持久化(需配置),事务确认 | 分区顺序(默认),全局顺序需额外配置 | 小规模系统,灵活路由 | 需手动管理事务,性能较高 |
| Kafka | 持久化日志(默认),事务支持 | 分区顺序(默认),全局顺序需事务 | 大规模高吞吐,持久化强 | 需考虑分区数量,顺序保证需事务 |
| RocketMQ | 持久化存储(默认),事务消息 | 全局顺序(默认),分区顺序 | 金融等高可靠性场景 | 顺序保证性能较高,支持分布式事务 |
4) 【示例】
订单消息路由设计:
订单消息结构:{ "orderId": "1001", "userId": "u001", "exchangeId": "GZFE", "orderType": "buy", "price": 100, "quantity": 10 }
路由键设计为order:GZFE:u001,持久化存储到Kafka的“order_topic”,使用Kafka的Producer-Consumer事务(AT模式),确保消息写入分区前、消费者处理前不丢失。顺序保证:按订单ID升序排序,确保撮合引擎按时间顺序处理订单。
伪代码(Producer发送消息):
producer = KafkaProducer(
bootstrap_servers='kafka:9092',
acks='all', # 确保消息写入磁盘
transactional_id='order_tx'
)
producer.initTransactions()
producer.beginTransaction()
try:
producer.send(
topic='order_topic',
key='order:GZFE:u001',
value=json.dumps(order_msg),
partition=0 # 按exchangeId分区
)
producer.commitTransaction()
except Exception as e:
producer.abortTransaction()
raise e
5) 【面试口播版答案】
面试官您好,关于期货交易系统选择消息队列时考虑消息持久化、顺序保证及路由策略,核心是要确保订单消息在撮合前不丢失且处理顺序正确。首先,消息持久化方面,我们选择支持磁盘持久化的消息队列(如Kafka或RocketMQ),通过配置acks='all'或事务机制,确保消息写入磁盘,避免系统故障导致丢失。其次,顺序保证,对于订单消息,我们采用分区顺序(按交易所ID或用户ID分区),确保同一交易所的订单按发送顺序处理,同时全局顺序通过事务保证(如RocketMQ的全局顺序消息),避免跨分区乱序。路由策略上,订单消息的路由键设计为order:交易所ID:用户ID,例如订单ID为1001,用户u001,交易所GZFE,路由键为order:GZFE:u001,这样消息会被分发到对应交易所的撮合节点,确保每个交易所的订单由其专属节点处理。通过这种设计,订单消息在写入队列前已持久化,处理时按分区顺序,路由到正确节点,从而保证撮合前不丢失且处理顺序正确。
6) 【追问清单】
limit:exchange:userId,不影响现有路由。7) 【常见坑/雷区】
acks='all'或事务,消息写入磁盘前丢失。