撮合系统的数据流转过程

在这里插入图片描述
可以看到,数据源有两个,一个是 DB,另一个是消息队列。主要的流程都是,数据源发送到 Disruptor 框架的 ringBuffer 里,通过 Disruptor 自带的队列监听机制,触发放入 ringBuffer 里 Event 对应的 EventHandler 的 onEvent 方法,在 onEvent 方法完成具体的撮合逻辑。

1、从 DB 来的数据源

程序启动时,直接从数据库捞数据,实现 springboot 的一个启动类

@Component
public class DataLoaderCmdRunner implements CommandLineRunner {


    @Autowired
    private EntrustOrderMapper entrustOrderMapper ;

    @Autowired
    private DisruptorTemplate disruptorTemplate ;
    /**
     * 项目启动完毕后会执行该方法
     * @param args
     * @throws Exception
     */
    @Override
    public void run(String... args) throws Exception {
        List<EntrustOrder> entrustOrders = entrustOrderMapper.selectList(
                new LambdaQueryWrapper<EntrustOrder>()
                        .eq(EntrustOrder::getStatus, 0)
                        .orderByAsc(EntrustOrder::getCreated)
        );
        if(CollectionUtils.isEmpty(entrustOrders)){
            return;
        }
        StopWatch stopWatch = new StopWatch() ;
        stopWatch.start();
        for (EntrustOrder entrustOrder : entrustOrders) {
            disruptorTemplate.onData(BeanUtils.entrustOrder2Order(entrustOrder));
        }
        stopWatch.stop();
        long lastTaskTimeMillis = stopWatch.getLastTaskTimeMillis();
        System.out.println("总条数:+"+entrustOrders.size()+" ,总共耗时:"+lastTaskTimeMillis+"ms");

    }


}

可以看到 disruptorTemplate.onData 就是具体的往 ringBuffer 里塞数据,塞的 Event 实际的类型就是 OrderEvent

 public void onData(Order input) {
        ringBuffer.publishEvent(TRANSLATOR, input);
    }
     private static final EventTranslatorOneArg<OrderEvent, Order> TRANSLATOR = new EventTranslatorOneArg<OrderEvent, Order>() {

        public void translateTo(OrderEvent event, long sequence, Order input) {
            event.setSource(input);
        }
    };

然后我们找到 OrderEventHandler implements EventHandler 的 onEvent 里,最终通过 match策略完成一个撮合,整个流程就是这样。

    @Override
    public void onEvent(OrderEvent event, long sequence, boolean endOfBatch) throws Exception {
        // 从ringbuffer 里面接收了某个数据
        Order order = (Order)event.getSource();
        if(!order.getSymbol().equals(symbol)){ // 我们接收到了一个不属于我们处理的数据,我们不处理
            return;
        }

//        log.info("开始接收订单事件============>{}", event);

        MatchServiceFactory.getMatchService(MatchStrategy.LIMIT_PRICE).match(orderBooks ,order);

        /// 处理逻辑是啥?
//        log.info("处理完成我们的订单事件===================>{}", event);
    }

值得注意的是,我们往容器中注入了一个什么样的 ringBuffer,com.bjsxt.disruptor.DisruptorAutoConfiguration#ringBuffer

public RingBuffer<OrderEvent> ringBuffer(
            EventFactory<OrderEvent> eventFactory,
            ThreadFactory threadFactory,
            WaitStrategy waitStrategy,
            EventHandler<OrderEvent>[] eventHandlers
    )

可以看到一个重要的构造参数 eventHandlers,这个数组就是所有可以监听 这个 ringBuffer 的 handler,我们往容器中注入的是根据配置文件里的交易对注入的3个

@Bean("eventHandlers")
    public EventHandler<OrderEvent>[] eventHandlers() {
        Map<String, MatchEngineProperties.CoinScale> symbols = matchEngineProperties.getSymbols();
        Set<Map.Entry<String, MatchEngineProperties.CoinScale>> entries = symbols.entrySet();
        EventHandler<OrderEvent>[] eventHandlers = new EventHandler[symbols.size()];
        int i = 0;
        for (Map.Entry<String, MatchEngineProperties.CoinScale> entry : entries) {
            String symbol = entry.getKey();
            MatchEngineProperties.CoinScale value = entry.getValue();
            OrderBooks orderBooks = null;
            if (value != null) {
                orderBooks = new OrderBooks(symbol, value.getCoinScale(), value.getBaseCoinScale());
            } else {
                orderBooks = new OrderBooks(symbol);
            }
            eventHandlers[i++] = new OrderEventHandler(orderBooks);
        }
        return eventHandlers;

    }
  #      去 nacos-server 里面拉取 match-service-dev.yaml
  match:
    symbols:
      BTCGCN:
        coinScale: 8
        baseCoinScale: 8
      ETHGCN:
        coinScale: 8
        baseCoinScale: 8
      FOFTGCN:
        coinScale: 8
        baseCoinScale: 8

2、通过 rockmq 发送数据源的数据流转

在交易系统中,创建委托单后,直接往 rockmq 中发送消息,撮合系统监听这个消息,将消息放到 ringbuffer 中
com.bjsxt.service.impl.EntrustOrderServiceImpl#createEntrustOrder
在这里插入图片描述
撮合系统监听,发送到 ringBuffer

@Service
@Slf4j
public class MessageConsumerListener {

    @Autowired
    private DisruptorTemplate disruptorTemplate;

    @StreamListener("order_in")
    public void handleMessage(EntrustOrder entrustOrder) {
        Order order = null;
        if (entrustOrder.getStatus() == 2) { // 该单需要取消
            order = new Order();
            order.setOrderId(entrustOrder.getId().toString());
            order.setCancelOrder(true);
        } else {
            order = BeanUtils.entrustOrder2Order(entrustOrder);
        }
        log.info("接收到了委托单:{}", order);
        disruptorTemplate.onData(order);
    }
}
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值