消息队列的使用

https://tva1.sinaimg.cn/large/007S8ZIlly1ggplxr68dcj30rd0o6h1q.jpg

交换机

  1. 订单事件交换机
  2. 库存事件交换机

延时队列

不使用消息计时:MQ使用惰性检查。

将30分钟后的消息,交给死信交换机,再进入订单释放队列。

订单

创建订单

将订单放入订单延时队列

rabbitTemplate.convertAndSend("order-event-exchange", "order.create.order", order.getOrderEntity());

主动取消订单

rabbitTemplate.convertAndSend("order-event-exchange", "order.release.other", orderTo);

监听订单

@RabbitHandler
    public void listenner(OrderEntity entity, Channel channel, Message message) throws IOException {
        System.out.println("收到过期的订单信息,准备关闭订单:" + entity.getOrderSn());
        try {
            orderService.closeOrder(entity);
            //TODO 手动调用支付宝收单,预防网络异常和服务器宕机
            channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
        } catch (Exception e) {
            channel.basicReject(message.getMessageProperties().getDeliveryTag(), true);
        }
    }

支付成功

库存

库存锁定

rabbitTemplate.convertAndSend("stock-event-exchange", "stock.locked", stockLockedTo);

库存自动解锁

下订单成功,库存锁定成功,但是后面的业务调用失败了,导致订单回滚,那么之前锁定的库存就要解锁。只要解锁库存失败,就要告诉服务器解锁失败,消息不能删除

根据工作单的状态,判断是否解锁。

@RabbitHandler
public void handleStockLockedRelease(StockLockedTo stockLockedTo, Message message, Channel channel) throws IOException {
        log.info("******收到解锁库存的信息******");
        try {
            wareSkuService.buidUnlockStock(stockLockedTo);
            // 手动删除消息
            channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
        } catch (Exception e) {
            // 解锁失败 将消息重新放回队列,让别人消费
            channel.basicReject(message.getMessageProperties().getDeliveryTag(), true);
        }
}

关闭订单解锁库存

@RabbitHandler
public void handleOrderCloseRelease(OrderTo orderTo, Message message, Channel channel) throws IOException {
        log.info("******收到订单关闭,准备解锁库存的信息******");
        try {
            wareSkuService.buidUnlockStock(orderTo);
            // 手动删除消息
            channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
        } catch (Exception e) {
            // 解锁失败 将消息重新放回队列,让别人消费
            channel.basicReject(message.getMessageProperties().getDeliveryTag(), true);
        }
    }