RabbitMQ之Consumer消费模式(Push & Pull)

概述

消息中间件有很多种,进程也会拿几个来对比对比,其中一种对比项就是消费模式。消息的消费模式分Push、Pull两种,或者两者兼具。RabbitMQ的消费模式就是兼具Push和Pull。
本文通过demo代码以及借助wireshark抓包工具来观察RabbitMQ的消费模式。


欢迎支持笔者新作:《深入理解Kafka:核心设计与实践原理》和《RabbitMQ实战指南》,同时欢迎关注笔者的微信公众号:朱小厮的博客。
在这里插入图片描述
欢迎跳转到本文的原文链接:https://honeypps.com/mq/rabbitmq-consumer-consumption-pattern/

push模式

发送端向broker端发送数据,数据内容为:RabbitMQ Demo Test, Send Messages 0;RabbitMQ Demo Test, Send Messages 1;RabbitMQ Demo Test, Send Messages 2,一次类推……
下面是消费端的示例代码:

Connection connection = factory.newConnection();
Channel channel = connection.createChannel();
QueueingConsumer consumer = new QueueingConsumer(channel);
channel.basicQos(1);
channel.basicConsume(QUEUE_NAME, false, "consumer_zzh",consumer);

while (true) {
    QueueingConsumer.Delivery delivery = consumer.nextDelivery();
    String message = new String(delivery.getBody());
    System.out.println(" [X] Received '" + message + "'");
    channel.basicAck(delivery.getEnvelope().getDeliveryTag(),false);
    break;
}
channel.close();
connection.close();

运行输出:RabbitMQ Demo Test, Send Messages 0

通过wirkshark工具来查看上面示例代码的整个AMQP的过程(图1):
这里写图片描述

上图可以对照实例代码来看,比如图中:Basic.Qos和Basic.Qos-Ok就是示例代码中的:channel.basicQos(1);
再比如图中的Basic.Ack就是示例代码中的channel.basicAck(delivery.getEnvelope().getDeliveryTag(),false);
对于上图中的带蓝色背影的那行(即No.545,展开如下图,broker to client)
这里写图片描述

可以看到Delivery-Tag = 1, 消息内容:“RabbitMQ Demo Test, Send Messages 0”。
展开No.546,即Basic.Ack这行:
这里写图片描述

可以看到client to broker的Ack:delievery-tag=1,和上面的符合。
仔细的朋友可以看到No.548同样是broker向client发送了一条数据,通过展开数据可知:
这里写图片描述

其内包含的数据正好是下一条的消息——“RabbitMQ Demo Test, Send Messages 1”。但是在运行实例的时候是没有打印出来的,可以看图1,是broker端主动向client端发送的数据,client端没有请求。在broker端发送第一条数据,即"RabbitMQ Demo Test, Send Messages 0"之后发送Ack,之后关闭Channel,到真正关闭完channel之间,broker端还是会发送(push)数据给Client, 此时Client不会在Ack此条数据了。那么这样这条消息会不会丢失呢?答案是否定的,你可以再运行下consumer程序,就能消费到这条消息,rabbitmq对设置autoAck=false之后没有被Ack的消息是不会清除掉的。

实际上如果不设置channel.basicQos(1),那么broker端会一次推送多条数据
RabbitMQ的每一数据帧(Frame)都是以0xCE结尾。


pull模式

同样采用wirkshark工具来观察pull模式的AMQP过程,pull模式主要是通过channel,basicGet方法来获取消息,示例代码如下:

GetResponse response = channel.basicGet(QUEUE_NAME, false);
System.out.println(new String(response.getBody()));
channel.basicAck(response.getEnvelope().getDeliveryTag(),false);

wireshark抓包结果:
这里写图片描述

可以观察No.122, No.123, No.124,这些对于上面的示例代码。
首先是client端发送Get请求,然后broker响应请求回传消息,最后client端发送Ack. 可以看到有别于push模式,broker端不会在client端没有请求的情况下来回传消息。

欢迎跳转到本文的原文链接:https://honeypps.com/mq/rabbitmq-consumer-consumption-pattern/


欢迎支持笔者新作:《深入理解Kafka:核心设计与实践原理》和《RabbitMQ实战指南》,同时欢迎关注笔者的微信公众号:朱小厮的博客。
在这里插入图片描述

  • 4
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 8
    评论
RabbitMQ是一个开源的消息中间件,它实现了高效的消息传递机制,可以在分布式系统中进行消息的发布和订阅。生产者消费模式是一种常见的消息通信模式,其中生产者负责发送消息,消费者负责接收和处理消息。 在RabbitMQ中,生产者和消费者之间通过交换机(Exchange)和队列(Queue)进行通信。生产者将消息发送到交换机,交换机根据指定的路由规则将消息路由到一个或多个队列中,消费者从队列中接收消息并进行处理。 在单机模式下,RabbitMQ的生产者和消费者都运行在同一台机器上。以下是单机模式RabbitMQ生产者消费者的基本步骤: 1. 安装RabbitMQ:首先需要在机器上安装RabbitMQ服务。 2. 创建连接:生产者和消费者都需要创建与RabbitMQ服务器的连接。连接包括主机名、端口号、用户名和密码等信息。 3. 创建通道:连接成功后,生产者和消费者都需要创建一个通道。通道是进行消息传递的通道,可以在同一个连接上创建多个通道。 4. 声明交换机:生产者需要声明一个交换机,用于将消息发送到指定的队列。交换机有不同的类型,如直连交换机、主题交换机、扇形交换机等。 5. 声明队列:消费者需要声明一个队列,用于接收生产者发送的消息。队列可以绑定到交换机上,以便接收特定类型的消息。 6. 发布消息:生产者通过通道将消息发送到交换机,指定消息的路由键和其他属性。 7. 消费消息:消费者通过通道从队列中接收消息,并进行处理。可以设置回调函数来处理接收到的消息。 8. 关闭连接:当生产者和消费者完成任务后,需要关闭与RabbitMQ服务器的连接。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值