當我把撮合引擎部屬到k8s上,水平擴張成多個節點時,最怕的是「同一張對手單被不同節點同時吃走」。這會導致重複成交或扣到負數。為了避免這種搶單,我在「事件層」與「資料層」各做一層保護。
order.created.queue 採 work-queue 模式:每一筆 order.created 只會送達其中一個消費者(節點)。
這代表「同一張 taker 訂單」只會有一個節點在處理,天然降低衝突機率。
@RabbitListener(queues = "order.created.queue")
public void handleConfirmedOrder(OrderCreatedEvent event) { ... }
真正會造成衝突的是「從對手簿取出 maker 的那一刻」。我把 取出最優一筆 + 立即移除 打包在 一支 Lua 中執行,Redis 會以單執行緒完成這個指令: