-
解决的问题:
- 商品的数据都在数据库中,对数据库的增删改查不能及时添加到搜索服务数据来源的索引库中,不能即使更新,比如上架,下架商品
- 数据库中的价格更新,索引库中的数据没有同步问题
-
解决方案
- 每当对后台增删改查,调用其他服务对索引库进行操作,增加了耦合,不合适
- 解决办法:消息队列
-
异步
-
并行
-
解耦
-
排队
-
基础概念
-
生产者---->交换机----->队列------>通道------>消费者
-
-
具体实现:
- 说明一下场景:
- service-product 连接后台系统,做商品上架下架,操作的是数据库,用rabbitMQ来通知 service-list 微服务 操作 同步上架,下架,操作索引库(因为页面显示是从索引库中查询出来的,ES 搜索引擎)
- 实现:
- 说明一下场景:
-
RabbitMQ自己写的一个工具类
-
封装发送端消息确认
/** * 封装发送端消息确认 */ @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); } }
-
发送消息
@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; } }
-
-
service-product用来发送RabbitMQ的
-
发送上架消息
@Autowired private RabbitService rabbitService; //上面这个 rabbitService 也就是调用的上面写的发送消息的那个 //保存sku信息,使用rabbitService // 发送数据 // 发送什么消息才能实现商品上架: 在service-list 中upperGoods(Long skuId) //参数为:虚拟机名称,队列名称,传的调用方法需要的参数 //与下架不同的是 队列名称不同 rabbitService.sendMessage(MqConst.EXCHANGE_DIRECT_GOODS,MqConst.ROUTING_GOODS_UPPER,skuInfo.getId());
-
发送下架消息
//rabbitService 使用MQ来通知server-list 上架 // 发送什么消息才能实现商品上架: 在service-list 中upperGoods(Long skuId) rabbitService.sendMessage(MqConst.EXCHANGE_DIRECT_GOODS, MqConst.ROUTING_GOODS_UPPER, skuId);
-
-
service-list 接收处理发送过来的RabbitMQ
-
//用来接收后台传递过来的消息队列,只用到了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); } }
-
RabbitMQ的使用
最新推荐文章于 2024-04-25 23:01:38 发布