RabbitMQ安装使用及数据同步

本文介绍了如何利用RabbitMQ解决商品详情和搜索系统数据同步问题,详细阐述了RabbitMQ的下载安装、消息模型(包括基本模型、work模型和订阅模型)、持久化策略,以及在SpringAMQP中应用消息队列进行项目改造,实现数据的自动同步。
摘要由CSDN通过智能技术生成


在这里插入图片描述
目前已经完成了商品详情和搜索系统的开发。思考一下,是否存在问题?

商品的原始数据保存在数据库中,增删改查都在数据库中完成。

搜索服务数据来源是索引库,如果数据库商品发生变化,索引库数据不能及时更新。

商品详情做了页面静态化,静态页面数据也不会随着数据库商品发生变化。

如果在后台修改了商品的价格,搜索页面和商品详情页显示的依然是旧的价格,这样显然不对。该如何解决?

这里有两种解决方案:

方案1:每当后台对商品做增删改操作,同时要修改索引库数据及静态页面

方案2:搜索服务和商品页面服务对外提供操作接口,后台在商品增删改后,调用接口

以上两种方式都有同一个严重问题:就是代码耦合,后台服务中需要嵌入搜索和商品页面服务,违背了微服务的独立原则。

所以,会通过另外一种方式来解决这个问题:消息队列。

下载和安装

下载

官网下载地址:http://www.rabbitmq.com/download.html

安装
Centos 7 安装RabbitMQ在这里插入图片描述

五种消息模型

RabbitMQ提供了6种消息模型,但是第6种其实是RPC,并不是MQ,因此不予学习。那么也就剩下5种。
但是其实3、4、5这三种都属于订阅模型,只不过进行路由的方式不同。
在这里插入图片描述

基本消息模型

在这里插入图片描述

RabbitMQ怎么知道消息被接收了?

因此,RabbitMQ有一个ACK机制。当消费者获取消息后,会向RabbitMQ发送回执ACK,告知消息已经被接收。不过这种回执ACK分两种情况:

  • 自动ACK:消息一旦被接收,消费者自动发送ACK
  • 手动ACK:消息接收后,不会发送ACK,需要手动调用
  • 如果消息不太重要,丢失也没有影响,那么自动ACK会比较方便
public class Recv {
   
    private final static String QUEUE_NAME = "simple_queue";

    public static void main(String[] argv) throws Exception {
   
        // 获取到连接
        Connection connection = ConnectionUtil.getConnection();
        // 创建通道
        Channel channel = connection.createChannel();
        // 声明队列
        channel.queueDeclare(QUEUE_NAME, false, false, false, null);
        // 定义队列的消费者
        DefaultConsumer consumer = new DefaultConsumer(channel) {
   
            // 获取消息,并且处理,这个方法类似事件监听,如果有消息的时候,会被自动调用
            @Override
            public void handleDelivery(String consumerTag, Envelope envelope, BasicProperties properties,
                    byte[] body) throws IOException {
   
                // body 即消息体
                String msg = new String(body);
                System.out.println(" [x] received : " + msg + "!");
            }
        };
        // 监听队列,第二个参数:是否自动进行消息确认。
        channel.basicConsume(QUEUE_NAME, true, consumer);
    }
}
  • 如果消息非常重要,不容丢失。那么最好在消费完成后手动ACK,否则接收消息后就自动ACK,RabbitMQ就会把消息从队列中删除。如果此时消费者宕机,那么消息就丢失了。
public class Recv2 {
   
    private final static String QUEUE_NAME = "simple_queue";

    public static void main(String[] argv) throws Exception {
   
        // 获取到连接
        Connection connection = ConnectionUtil.getConnection();
        // 创建通道
        final Channel channel = connection.createChannel();
        // 声明队列
        channel.queueDeclare(QUEUE_NAME, false, false, false, null);
        // 定义队列的消费者
        DefaultConsumer consumer = new DefaultConsumer(channel) {
   
            // 获取消息,并且处理,这个方法类似事件监听,如果有消息的时候,会被自动调用
            
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值