RabbitMQ之Consumer消费模式(Push & Pull)
版权声明:本文为博主原创文章,未经博主朱小厮允许不得转载。 https://blog.csdn.net/u013256816/article/details/62890189
概述
消息中间件有很多种,进程也会拿几个来对比对比,其中一种对比项就是消费模式。消息的消费模式分Push,Push两种,或者两者兼具。RabbitMQ的消费模式就是兼具Push和Pull。
本文通过demo代码以及借助wireshark抓包工具来观察RabbitMQ的消费模式。
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();
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
运行输出: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);
1
2
3
wireshark抓包结果:
可以观察No.122, No.123, No.124,这些对于上面的示例代码。
首先是client端发送Get请求,然后broker响应请求回传消息,最后client端发送Ack. 可以看到有别于push模式,broker端不会在client端没有请求的情况下来回传消息。
---------------------
作者:朱小厮
来源:CSDN
原文:https://blog.csdn.net/u013256816/article/details/62890189
版权声明:本文为博主原创文章,转载请附上博文链接!
RabbitMQ之Consumer消费模式(Push & Pull)的更多相关文章
- JMS学习(八)-ActiveMQ Consumer 使用 push 还是 pull 获取消息
ActiveMQ是一个消息中间件,对于消费者而言有两种方式从消息中间件获取消息: ①Push方式:由消息中间件主动地将消息推送给消费者:②Pull方式:由消费者主动向消息中间件拉取消息.看一段官网对P ...
- 理解bootstrap的列偏移offset 和 推拉push/pull的区别?
参考: http://www.cnblogs.com/jnslove/p/5430481.html & https://blog.csdn.net/hly_coder/article/deta ...
- MongoDB之$关键字及$修改器$set $inc $push $pull $pop
一.查询中常见的 等于 大于 小于 大于等于 小于等于 等于:用':' 大于:用'$gt' 小于:用'$lt' 大于等于:用'$gte' 小于等于:用'$lte' MongoDB的操作就是 ...
- MongoDB 之 $关键字 及 $修改器 $set $inc $push $pull $pop MongoDB - 4
我们在之前的 MongoDB 之 手把手教你增删改查 MongoDB - 2 中提到过 $set 这个系统关键字,用来修改值的对吧 但是MongoDB中类似这样的关键字有很多, $lt $gt $lt ...
- git push/pull时总需要输入用户名密码的解决方案
在提交项目代码或者拉代码的时候,git会让你输入用户名密码,解决方案:(我们公司用的是gitlab) 执行git config --global credential.helper store命令 然 ...
- 4,MongoDB 之 $关键字 及 $修改器 $set $inc $push $pull $pop MongoDB
MongoDB中的关键字有很多, $lt $gt $lte $gte 等等,这么多我们也不方便记,这里我们说说几个比较常见的 一.查询中常见的 等于 大于 小于 大于等于 小于等于 等于 : 在Mon ...
- Push pull, open drain circuit, pull up, pull down resistor
Push pull 就以下面這個 電路來說, 因為沒有 pull up resistor, 所以 output voltage 由 low 往 high 的速度會較快. 有兩個電晶體,一個on,一個 ...
- MongoDB之$关键字,以及$修饰器$set,$inc,$push,$pull,$pop
一.查询中常见的 等于 大于 小于 大于等于 小于等于 等于:在MongoDB中,什么字段等于什么值就是" : ",比如 "name":"路飞学城&q ...
- 2.每人自己建立一个HelloWorld项目,练习使用git的add/commit/push/pull/fetch/clone等基本命令。比较项目的新旧版本的差别。答题人:张立鹏
第1步:创建SSH Key.在用户主目录下,看看有没有.ssh目录,如果有,再看看这个目录下有没有id_rsa和id_rsa.pub这两个文件,如果已经有了,可直接跳到下一步.如果没有,打开Shell ...
随机推荐
- python_初步
官网地址:http://www.python.org/ Python最新源码,二进制文档,新闻资讯 Python文档下载地址:www.python.org/doc/ python教程:http://w ...
- SMM+maven下的log4j配置打印sql
1加入依赖包 <!--LOG4日志 start --> <dependency> <groupId>org.slf4j</groupId> <ar ...
- 一图看懂join、left join、right join、fulljoin间的区别
INNER JOIN 关键字在表中存在至少一个匹配时返回行. LEFT JOIN 关键字从左表(table1)返回所有的行,即使右表(table2)中没有匹配.如果右表中没有匹配,则结果为 NULL. ...
- 分布式技术 webapi
webapi可以返回json.xml类型的数据,对于数据的增.删.改.成,提供对应的资源操作,按照请求的类型进行相应的处理,主要包括 Get(查).Post(增).Put(改).Delete(删),这 ...
- Pandas数据帧(DataFrame)
数据帧(DataFrame)是二维数据结构,即数据以行和列的表格方式排列. 数据帧(DataFrame)的功能特点: 潜在的列是不同的类型 大小可变 标记轴(行和列) 可以对行和列执行算术运算 结构体 ...
- JNI_Z_05_方法的操作(没有String类型的参数)
1.步骤: (1).获取 jclass (2).获取 method的id (3).调用 method ZC: 貌似 JNI里面 操作 类的方法,完全是 无视 访问权限的... 然而 static的方法 ...
- d3.js学习笔记(五)——将数据结构化为D3.js可处理的
目标 在这一章,你将会理解如何对数据进行结构化,来更好的使用D3.js. 我们将会回顾我们之前已经学习的,学习D3.js如何使用选集(selections),JavaScript对象基础,以及如何最优 ...
- 如何在修改bug时切换分支保留修改又不提交
使用git的时候,我们往往使用branch解决任务切换问题,例如,我们往往会建一个自己的分支去修改和调试代码, 如果别人或者自己发现原有的分支上有个不得不修改的bug,我们往往会把完成一半的代码 co ...
- 原生javascript-图片弹窗交互效果
本人的第一个原生js插件 - picLightBox 在线例子:http://lgy.1zwq.com/photoBox/ [一]用var 声明多个变量,比每个变量都用var快多了 var sScro ...
- 利用 innodb_force_recovery 解决MySQL服务器crash无法重启问题
背景 MySQL服务器因为磁盘阵列损坏机器crash,重启MySQL服务时 报如下错误: InnoDB: Reading tablespace information from the .i ...