RabbitMQ操作

RabbitMQ的消息模

在这里插入图片描述
在这里插入图片描述

业务场景说明

用于解决用户下单以后,订单超时如何取消订单的问题。

用户进行下单操作(会有锁定商品库存、使用优惠券、积分一系列的操作);

生成订单,获取订单的id;

获取到设置的订单超时时间(假设设置的为60分钟不支付取消订单);

按订单超时时间发送一个延迟消息给RabbitMQ,让它在订单超时后触发取消订单的操作;

如果用户没有支付,进行取消订单操作(释放锁定商品库存、返还优惠券、返回积分一系列操作)。

整合RabbitMQ实现延迟消息

在pom.xml中添加相关依赖

 <dependency> 
  <groupId>org.springframework.boot</groupId>   
  <artifactId>spring-boot-starter-amqp</artifactId>
  </dependency>
  

修改SpringBoot配置文件
修改application.yml文件,在spring节点下添加RabbitMQ相关配置。

rabbitmq:
host: localhost
port: 5672
virtual-host: /mall
username: mall
password: mall
publisher-confirms: true #如果对异步消息需要回调必须设置为true

在这里插入图片描述
添加消息队列的枚举配置类QueueEnum

用于延迟消息队列及处理取消订单消息队列的常量定义,包括交换机名称、队列名称、路由键名称。

/**

  • 消息队列枚举配置

  • Created by macro on 2018/9/14.
    /
    @Getter
    public enum QueueEnum {
    /
    *

    • 消息通知队列
      /
      QUEUE_ORDER_CANCEL(“mall.order.direct”, “mall.order.cancel”, “mall.order.cancel”),
      /
      *
    • 消息通知ttl队列
      */
      QUEUE_TTL_ORDER_CANCEL(“mall.order.direct.ttl”, “mall.order.cancel.ttl”, “mall.order.cancel.ttl”);

    /**

    • 交换名称
      /
      private String exchange;
      /
      *
    • 队列名称
      /
      private String name;
      /
      *
    • 路由键
      */
      private String routeKey;

    QueueEnum(String exchange, String name, String routeKey) {
    this.exchange = exchange;
    this.name = name;
    this.routeKey = routeKey;
    }

添加RabbitMQ的配置

用于配置交换机、队列及队列与交换机的绑定关系。
/**

  • 消息队列配置

  • Created by macro on 2018/9/14.
    */
    @Configuration
    public class RabbitMqConfig {

    /**

    • 订单消息实际消费队列所绑定的交换机
      */
      @Bean
      DirectExchange orderDirect() {
      return (DirectExchange) ExchangeBuilder
      .directExchange(QueueEnum.QUEUE_ORDER_CANCEL.getExchange())
      .durable(true)
      .build();
      }

    /**

    • 订单延迟队列队列所绑定的交换机
      */
      @Bean
      DirectExchange orderTtlDirect() {
      return (DirectExchange) ExchangeBuilder
      .directExchange(QueueEnum.QUEUE_TTL_ORDER_CANCEL.getExchange())
      .durable(true)
      .build();
      }

    /**

    • 订单实际消费队列
      */
      @Bean
      public Queue orderQueue() {
      return new Queue(QueueEnum.QUEUE_ORDER_CANCEL.getName());
      }

    /**

    • 订单延迟队列(死信队列)
      */
      @Bean
      public Queue orderTtlQueue() {
      return QueueBuilder
      .durable(QueueEnum.QUEUE_TTL_ORDER_CANCEL.getName())
      .withArgument(“x-dead-letter-exchange”, QueueEnum.QUEUE_ORDER_CANCEL.getExchange())//到期后转发的交换机
      .withArgument(“x-dead-letter-routing-key”, QueueEnum.QUEUE_ORDER_CANCEL.getRouteKey())//到期后转发的路由键
      .build();
      }

    /**

    • 将订单队列绑定到交换机
      */
      @Bean
      Binding orderBinding(DirectExchange orderDirect,Queue orderQueue){
      return BindingBuilder
      .bind(orderQueue)
      .to(orderDirect)
      .with(QueueEnum.QUEUE_ORDER_CANCEL.getRouteKey());
      }

    /**

    • 将订单延迟队列绑定到交换机
      */
      @Bean
      Binding orderTtlBinding(DirectExchange orderTtlDirect,Queue orderTtlQueue){
      return BindingBuilder
      .bind(orderTtlQueue)
      .to(orderTtlDirect)
      .with(QueueEnum.QUEUE_TTL_ORDER_CANCEL.getRouteKey());
      }

}

在RabbitMQ管理页面可以看到以下交换机和队列

在这里插入图片描述

交换机及队列说明

mall.order.direct(取消订单消息队列所绑定的交换机):绑定的队列为mall.order.cancel,一旦有消息以mall.order.cancel为路由键发过来,会发送到此队列。
mall.order.direct.ttl(订单延迟消息队列所绑定的交换机):绑定的队列为mall.order.cancel.ttl,一旦有消息以mall.order.cancel.ttl为路由键发送过来,会转发到此队列,并在此队列保存一定时间,等到超时后会自动将消息发送到mall.order.cancel(取消订单消息消费队列)。

添加延迟消息的发送者CancelOrderSender

用于向订单延迟消息队列(mall.order.cancel.ttl)里发送消息。
/**

  • 取消订单消息的发出者

  • Created by macro on 2018/9/14.
    */
    @Component
    public class CancelOrderSender {
    private static Logger LOGGER =LoggerFactory.getLogger(CancelOrderSender.class);
    @Autowired
    private AmqpTemplate amqpTemplate;

    public void sendMessage(Long orderId,final long delayTimes){
    //给延迟队列发送消息
    amqpTemplate.convertAndSend(QueueEnum.QUEUE_TTL_ORDER_CANCEL.getExchange(), QueueEnum.QUEUE_TTL_ORDER_CANCEL.getRouteKey(), orderId, new MessagePostProcessor() {
    @Override
    public Message postProcessMessage(Message message) throws AmqpException {
    //给消息设置延迟毫秒值
    message.getMessageProperties().setExpiration(String.valueOf(delayTimes));
    return message;
    }
    });
    LOGGER.info(“send orderId:{}”,orderId);
    }
    }

添加取消订单消息的接收者CancelOrderReceiver

用于从取消订单的消息队列(mall.order.cancel)里接收消息。

/**

  • 取消订单消息的处理者
  • Created by macro on 2018/9/14.
    */
    @Component
    @RabbitListener(queues = “mall.order.cancel”)
    public class CancelOrderReceiver {
    private static Logger LOGGER =LoggerFactory.getLogger(CancelOrderReceiver.class);
    @Autowired
    private OmsPortalOrderService portalOrderService;
    @RabbitHandler
    public void handle(Long orderId){
    portalOrderService.cancelOrder(orderId);
    LOGGER.info(“process orderId:{}”,orderId);
    }
    }

添加OmsPortalOrderService接口

**

  • 前台订单管理Service

  • Created by macro on 2018/8/30.
    */
    public interface OmsPortalOrderService {

    /**

    • 根据提交信息生成订单
      */
      @Transactional
      CommonResult generateOrder(OrderParam orderParam);

    /**

    • 取消单个超时订单
      */
      @Transactional
      void cancelOrder(Long orderId);

}

添加OmsPortalOrderService的实现类OmsPortalOrderServiceImpl

在这里插入图片描述

添加OmsPortalOrderController定义接口

在这里插入图片描述

进行接口测试

调用下单接口

注意:已经将延迟消息时间设置为30秒
在这里插入图片描述

项目源码地址
https://github.com/macrozheng/mall-learning/tree/master/mall-tiny-08
原文地址:
https://mp.weixin.qq.com/s?__biz=MzU1Nzg4NjgyMw==&mid=2247483734&idx=1&sn=fa9af8e9f72e7443126aed0f7a64b88b&scene=21#wechat_redirect

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值