RabbitMQ的使用

  1. 解决的问题:

    1. 商品的数据都在数据库中,对数据库的增删改查不能及时添加到搜索服务数据来源的索引库中,不能即使更新,比如上架,下架商品
    2. 数据库中的价格更新,索引库中的数据没有同步问题
  2. 解决方案

    1. 每当对后台增删改查,调用其他服务对索引库进行操作,增加了耦合,不合适
    2. 解决办法:消息队列
      1. 异步在这里插入图片描述

      2. 并行在这里插入图片描述

      3. 解耦在这里插入图片描述

      4. 排队在这里插入图片描述

      5. 基础概念在这里插入图片描述

      6. 生产者---->交换机----->队列------>通道------>消费者

  3. 具体实现:

    1. 说明一下场景:
      1. service-product 连接后台系统,做商品上架下架,操作的是数据库,用rabbitMQ来通知 service-list 微服务 操作 同步上架,下架,操作索引库(因为页面显示是从索引库中查询出来的,ES 搜索引擎)
    2. 实现:
  4. RabbitMQ自己写的一个工具类

    1. 封装发送端消息确认

      /**
       * 封装发送端消息确认
       */
      @Component
      public class MQProducerAckConfig implements RabbitTemplate.ReturnCallback,RabbitTemplate.ConfirmCallback {
      
          /**
           * 表示消息是否发到了交换机,如果消息发送到了交换机,或者没有发送到交换机,都会走这个方法
           * @param correlationData 封装数据发送的内容
           * @param ack 判断是否到达交换机
           * @param cause 没有到达的原因
           */
          @Override
          public void confirm(CorrelationData correlationData, boolean ack, String cause) {
              if (ack){
                  System.out.println("发送到达了交换机,成功!"+cause);
              }else {
                  System.out.println("没有到大交换机,失败!"+cause);
              }
          }
      
          /**
           *判断消息是否发送到队列,如果发送到队列,这个方法就不会走,如果没有,就会执行
           * @param message   消息的内容
           * @param replyCode 响应码
           * @param replyText 响应内容
           * @param exchange  交换机
           * @param routingKey   路由键
           */
          @Override
          public void returnedMessage(Message message, int replyCode, String replyText, String exchange, String routingKey) {
              System.out.println("消息主体: " + new String(message.getBody()));
              System.out.println("应答码: " + replyCode);
              System.out.println("描述:" + replyText);
              System.out.println("消息使用的交换器 exchange : " + exchange);
              System.out.println("消息使用的路由键 routing : " + routingKey);
          }
      }
      
    2. 发送消息

      @Service
      public class RabbitService {
          @Autowired
          private RabbitTemplate rabbitTemplate;
          /**
           * 制作一个发送消息的方法
           * @param exchange  交换机
           * @param routingKey  路由键
           * @param message   消息的内容
           * @return
           */
          public boolean sendMessage(String  exchange,String routingKey,Object message){
               rabbitTemplate.convertAndSend(exchange,routingKey,message);
              return true;
          }
      }
      
  5. service-product用来发送RabbitMQ的

    1. 发送上架消息

      @Autowired
       private RabbitService rabbitService;
      //上面这个 rabbitService  也就是调用的上面写的发送消息的那个
      
      
      //保存sku信息,使用rabbitService
       // 发送数据
       // 发送什么消息才能实现商品上架: 在service-list 中upperGoods(Long skuId)
      //参数为:虚拟机名称,队列名称,传的调用方法需要的参数
      //与下架不同的是 队列名称不同
      rabbitService.sendMessage(MqConst.EXCHANGE_DIRECT_GOODS,MqConst.ROUTING_GOODS_UPPER,skuInfo.getId());
      
    2. 发送下架消息

      //rabbitService 使用MQ来通知server-list 上架
              // 发送什么消息才能实现商品上架: 在service-list 中upperGoods(Long skuId)
              rabbitService.sendMessage(MqConst.EXCHANGE_DIRECT_GOODS, MqConst.ROUTING_GOODS_UPPER, skuId);
      
  6. service-list 接收处理发送过来的RabbitMQ

    1. //用来接收后台传递过来的消息队列,只用到了MQ
      @Component
      public class ListReceiver {
          @Autowired
          private SearchService searchService;
      
          //使用注解
          //处理商品上架
          @SneakyThrows
          @RabbitListener(bindings = @QueueBinding(
                  // durable 是否持久化 autoDelete 是否自动删除
                  value = @Queue(value = MqConst.QUEUE_GOODS_UPPER,autoDelete = "false",durable = "true"),
                  exchange = @Exchange(value = MqConst.EXCHANGE_DIRECT_GOODS),
                  key = {MqConst.ROUTING_GOODS_UPPER}
          ))
          public void upperGoods(Long skuId, Message message, Channel channel){
              if (null!=skuId){
                  searchService.upperGoods(skuId);
              }
              //手动收到 ask
              channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
          }
          //使用注解
          //处理商品下架
          @SneakyThrows
          @RabbitListener(bindings = @QueueBinding(
                  // durable 是否持久化
                  value = @Queue(value = MqConst.QUEUE_GOODS_LOWER,autoDelete = "false",durable = "true"),
                  exchange = @Exchange(value = MqConst.EXCHANGE_DIRECT_GOODS),
                  key = {MqConst.ROUTING_GOODS_LOWER}
          ))
          public void lowerGoods(Long skuId, Message message, Channel channel){
              if (null!=skuId){
                  searchService.lowerGoods(skuId);
              }
              //手动收到 ask
              channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
          }
      }
      
      
      
            
      
      
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值