RabbitMQ---基本消息模型

这篇具有很好参考价值的文章主要介绍了RabbitMQ---基本消息模型。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1、 基本消息模型

官方介绍:

RabbitMQ是一个消息代理:它接受和转发消息。 你可以把它想象成一个邮局:当你把邮件放在邮箱里时,你可以确定邮差先生最终会把邮件发送给你的收件人。
在这个比喻中,RabbitMQ是邮政信箱,邮局和邮递员。
RabbitMQ与邮局的主要区别是它不处理纸张,而是接受,存储和转发数据消息的二进制数据块。
RabbitMQ---基本消息模型,Spring Cloud,rabbitmq,中间件,服务器,后端,分布式

• P(producer/ publisher):生产者,一个发送消息的用户应用程序。
• C(consumer):消费者,消费和接收有类似的意思,消费者是一个主要用来等待接收消息的用户应用程序
• 队列(红色区域):rabbitmq内部类似于邮箱的一个概念。
• 虽然消息流经rabbitmq和你的应用程序,但是它们只能存储在队列中。
• 队列只受主机的内存和磁盘限制,实质上是一个大的消息缓冲区。
• 许多生产者可以发送消息到一个队列,许多消费者可以尝试从一个队列接收数据。
• 总之:
o 生产者将消息发送到队列,消费者从队列中获取消息,队列是存储消息的缓冲区。
o 我们将用Java编写两个程序;发送单个消息的生产者,以及接收消息并将其打印出来的消费者。
o 我们将详细介绍Java API中的一些细节,这是一个消息传递的“Hello World”。
o 我们将调用我们的消息发布者(发送者)Send和我们的消息消费者(接收者)Recv。
o 发布者将连接到RabbitMQ,发送一条消息,然后退出。

1.1、 生产者发送消息

import com.atuigu.rabbitmq.util.ConnectionUtil;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
public class Send {
    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);
        // 消息内容
        String message = "Hello World!";
        // 向指定的队列中发送消息
        channel.basicPublish("", QUEUE_NAME, null, message.getBytes());
        System.out.println(" [x] Sent '" + message + "'");
        //关闭通道和连接
        channel.close();
        connection.close();
    }
}
 API:
/ **
  * 声明队列
  * @param queue队列名称
  * @param durable  如果我们声明一个持久队列,则为true(该队列将在服务器重启后继续存在)
  * @param Exclusive 如果我们声明一个排他队列,则为true(仅限此连接)
  * @param autoDelete 如果我们声明一个自动删除队列,则为true(服务器将在不再使用它时将其删除)
  * @param arguments 参数队列的其他属性(构造参数)
  * @return一个声明确认方法来指示队列已成功声明
  * /
Queue.DeclareOk queueDeclare(String queue, boolean durable, boolean exclusive, boolean autoDelete,Map<String, Object> arguments) throws IOException;

控制台:
RabbitMQ---基本消息模型,Spring Cloud,rabbitmq,中间件,服务器,后端,分布式

1.2、管理工具中查看消息

进入队列页面,可以看到新建了一个队列:simple_queue
RabbitMQ---基本消息模型,Spring Cloud,rabbitmq,中间件,服务器,后端,分布式

点击队列名称,进入详情页,可以查看消息:
RabbitMQ---基本消息模型,Spring Cloud,rabbitmq,中间件,服务器,后端,分布式

在控制台查看消息并不会将消息消费,所以消息还在。

1.3、消费者获取消息

import com.rabbitmq.util.ConnectionUtil;
import com.rabbitmq.client.*;
import java.io.IOException;
/**
 * 消费者
 */
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, AMQP.BasicProperties properties,byte[] body) throws IOException {
                // body 即消息体
                String msg = new String(body);
                System.out.println(" [x] received : " + msg + "!");
            }
        };
        // 监听队列,第二个参数:是否自动进行消息确认。
        channel.basicConsume(QUEUE_NAME, true, consumer);
    }
}

控制台:
RabbitMQ---基本消息模型,Spring Cloud,rabbitmq,中间件,服务器,后端,分布式

这个时候,队列中的消息就没了:
RabbitMQ---基本消息模型,Spring Cloud,rabbitmq,中间件,服务器,后端,分布式

我们发现,消费者已经获取了消息,但是程序没有停止,一直在监听队列中是否有新的消息。一旦有新的消息进入队列,就会立即打印。

1.4、 消息确认机制(ACK)

• 通过刚才的案例可以看出,消息一旦被消费者接收,队列中的消息就会被删除。
• 那么问题来了:RabbitMQ怎么知道消息被接收了呢?
• 如果消费者领取消息后,还没执行操作就挂掉了呢?或者抛出了异常?消息消费失败,但是RabbitMQ无从得知,这样消息就丢失了!
• 因此,RabbitMQ有一个ACK机制。当消费者获取消息后,会向RabbitMQ发送回执ACK,告知消息已经被接收。
• 不过这种回执ACK分两种情况:
o 自动ACK:消息一旦被接收,消费者自动发送ACK
o 手动ACK:消息接收后,不会发送ACK,需要手动调用
• 大家觉得哪种更好呢?
• 这需要看消息的重要性:
o 如果消息不太重要,丢失也没有影响,那么自动ACK会比较方便
o 如果消息非常重要,不容丢失。那么最好在消费完成后手动ACK,否则接收消息后就自动ACK,RabbitMQ就会把消息从队列中删除。如果此时消费者宕机,那么消息就丢失了。
• 我们之前的测试都是自动ACK的,如果要手动ACK,需要改动我们的代码:

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) {
           // 获取消息,并且处理,这个方法类似事件监听,如果有消息的时候,会被自动调用
           @Override
           public void handleDelivery(String consumerTag, Envelope envelope, BasicProperties properties,
                   byte[] body) throws IOException {
               // body 即消息体
               String msg = new String(body);
        //int i = 1/0;
               System.out.println(" [x] received : " + msg + "!");
               // 手动进行ACK
               channel.basicAck(envelope.getDeliveryTag(), false);
           }
       };
       // 监听队列,第二个参数false,手动进行ACK
       channel.basicConsume(QUEUE_NAME, false, consumer);
   }
}

注意到最后一行代码:
channel.basicConsume(QUEUE_NAME, false, consumer);
如果第二个参数为true,则会自动进行ACK;如果为false,则需要手动ACK。方法的声明:
RabbitMQ---基本消息模型,Spring Cloud,rabbitmq,中间件,服务器,后端,分布式

1.5、自动ACK存在的问题

修改消费者,添加异常,如下:
RabbitMQ---基本消息模型,Spring Cloud,rabbitmq,中间件,服务器,后端,分布式

生产者不做任何修改,直接运行,消息发送成功:
RabbitMQ---基本消息模型,Spring Cloud,rabbitmq,中间件,服务器,后端,分布式

运行消费者,程序抛出异常。但是消息依然被消费:
RabbitMQ---基本消息模型,Spring Cloud,rabbitmq,中间件,服务器,后端,分布式

管理界面:
RabbitMQ---基本消息模型,Spring Cloud,rabbitmq,中间件,服务器,后端,分布式

1.6、演示手动ACK

修改消费者,把自动改成手动(去掉之前制造的异常)
RabbitMQ---基本消息模型,Spring Cloud,rabbitmq,中间件,服务器,后端,分布式

生产者不变,再次运行:
RabbitMQ---基本消息模型,Spring Cloud,rabbitmq,中间件,服务器,后端,分布式

运行消费者
RabbitMQ---基本消息模型,Spring Cloud,rabbitmq,中间件,服务器,后端,分布式

但是,查看管理界面,发现:
RabbitMQ---基本消息模型,Spring Cloud,rabbitmq,中间件,服务器,后端,分布式

停掉消费者的程序,发现:
RabbitMQ---基本消息模型,Spring Cloud,rabbitmq,中间件,服务器,后端,分布式

这是因为虽然我们设置了手动ACK,但是代码中并没有进行消息确认!所以消息并未被真正消费掉。
当我们关掉这个消费者,消息的状态再次称为Ready
修改代码手动ACK:
RabbitMQ---基本消息模型,Spring Cloud,rabbitmq,中间件,服务器,后端,分布式

执行:
RabbitMQ---基本消息模型,Spring Cloud,rabbitmq,中间件,服务器,后端,分布式

消息消费成功!文章来源地址https://www.toymoban.com/news/detail-673799.html

到了这里,关于RabbitMQ---基本消息模型的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 消息中间件管理系统-RabbitMQ及其两类传输模型

    微服务通讯有两种方式,同步和异步。客户端将请求发送到服务器, 异步通讯 较同步通讯而言,通过调用事件驱动模型Broker,无需等待服务器返回结果,微服务之间耦合度更低,微服务无需等待订阅者处理完成性能更好,并且做到了故障隔离,不存在级联失败等问题。 MQ,意

    2024年02月20日
    浏览(36)
  • 实战:Spring Cloud Stream消息驱动框架整合rabbitMq

    相信很多同学都开发过WEB服务,在WEB服务的开发中一般是通过缓存、队列、读写分离、削峰填谷、限流降级等手段来提高服务性能和保证服务的正常投用。对于削峰填谷就不得不用到我们的MQ消息中间件,比如适用于大数据的kafka,性能较高支持事务活跃度高的rabbitmq等等,MQ的

    2024年02月08日
    浏览(45)
  • Spring Cloud Stream 4.0.4 rabbitmq 发送消息多function

    注意当多个消费者时,需要添加配置项:spring.cloud.function.definition 启动日志 交换机名称对应: spring.cloud.stream.bindings.demo-in-0.destination配置项的值 队列名称是交换机名称+分组名 http://localhost:8080/sendMsg?delay=10000name=zhangsan 问题总结 问题一 解决办法: 查看配置是否正确: spring

    2024年02月19日
    浏览(44)
  • RabbitMQ---基本消息模型

    官方介绍: RabbitMQ是一个消息代理:它接受和转发消息。 你可以把它想象成一个邮局:当你把邮件放在邮箱里时,你可以确定邮差先生最终会把邮件发送给你的收件人。 在这个比喻中,RabbitMQ是邮政信箱,邮局和邮递员。 RabbitMQ与邮局的主要区别是它不处理纸张,而是接受,

    2024年02月11日
    浏览(38)
  • 在Spring Cloud中使用RabbitMQ完成一个消息驱动的微服务

    Spring Cloud系列目前已经有了Spring Cloud五大核心组件:分别是,Eureka注册中心,Zuul网关,Hystrix熔断降级,openFeign声明式远程调用,ribbon负载均衡。这五个模块,对了,有没有发现,其实我这五个模块中ribbon好像还没有案例例举,目前只有一个Ribbon模块的搭建,后边我会完善的

    2024年02月04日
    浏览(55)
  • RabbitMQ 消息中间件 消息队列

    RabbitMQ 1、RabbitMQ简介 RabbiMQ是⽤Erang开发的,集群⾮常⽅便,因为Erlang天⽣就是⼀⻔分布式语⾔,但其本身并 不⽀持负载均衡。支持高并发,支持可扩展。支持AJAX,持久化,用于在分布式系统中存储转发消息,在易用性、扩展性、高可用性等方面表现不俗。 2、RabbitMQ 特点 可

    2024年02月03日
    浏览(63)
  • 消息中间件RabbitMQ

    1.1.1. 什么是MQ MQ(message queue) ,从字面意思上看,本质是个队列,FIFO 先入先出,只不过队列中存放的内容是message 而已,还是一种跨进程的通信机制,用于上下游传递消息。在互联网架构中,MQ 是一种非常常见的上下游“逻辑解耦+物理解耦”的消息通信服务。使用了 MQ 之后,

    2024年01月17日
    浏览(81)
  • RabbitMQ消息中间件

    RabbitMQ消息中间件 RabbitMQ简介 windows下安装RabbitMQ RabbitMQ基本概念 RabbitMQ简单模式 RabbitMQ工作队列模式 RabbitMQ发布订阅模式 RabbitMQ路由模式 RabbitMQ主题模式 RabbitMQ RPC模式 RabbitMQ发布确认模式

    2024年02月10日
    浏览(57)
  • 消息中间件RabbitMQ详解

    消息中间件利用高效可靠的消息传递机制进行平台无关的数据交流,并基于数据通信来进行分布式系统的集成。通过提供消息传递和消息排队模型,它可以在分布式环境下扩展进程间的通信。 消息中间件适用于需要可靠的数据传送的分布式环境。采用消息中间件机制的系统中

    2024年02月16日
    浏览(77)
  • 消息中间件之RabbitMQ

    1.基于AMQP协议Erlang语言开发的一款消息中间件,客户端语言支持比较多, 比如Python,Java,Ruby,PHP,JS,Swift.运维简单,灵活路由,但是性能不高, 可以满足一般场景下的业务需要,三高场景下吞吐量不高,消息持久化没有采取 零拷贝技术,消息堆积时,性能会下降 2.消息吞吐量在

    2024年01月19日
    浏览(84)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包