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 ...
随机推荐
- StringUtils用法(isNotEmpty和isNotBlank)
isNotEmpty将空格也作为参数,isNotBlank则排除空格参数 参考 Quote StringUtils方法的操作对象是java.lang.String类型的对象,是JDK提供的String ...
- Oracle loop、while、for循环
Loop循环 Declare p_sum ; p_i number; Begin p_i :; Loop p_sum := p_sum + p_i; p_i :; ) then SYS.Dbms_Ou ...
- Makefile文件应用——simple项目
学习资料 本文主要参考资料:驾驭Makefile(李云).pdf 原理 (1)最基本的语法 targets: prerequisites command targets是目标,prerequisite ...
- 关于file_get_contents返回False的问题
在本地测试中,使用file_get_contents获取远程服务器的资源是可以的: public function send_post($url, $post_data = null) { $post ...
- js插件封装
插件封装原则 1.暴露出来的实例必须只能是一个 2.IIFE包裹 !执行包裹 函数作用域保护 3.实例化方法不要写在函数内 throw这个方法是报错
- scala学习手记35 - 隐式类型转换
先来看一下下面的内容: 2 days "ago" 5 days "from_now" 如上的内容具体应该是什么呢?不过怎么看也不像是代码.不过既然是在学代码,拿 ...
- const对象 不能调用非const修饰的成员函数
class class UIRect:public RECT { public: UIRect(LONG leftT = 0, LONG topT = 0, LONG rightT = 0, LONG ...
- shell编程-变量
Shell支持自定义变量. 定义变量 定义变量时,变量名不加美元符号($),如: VALUE=“tmp” 注意,变量名和等号之间不能有空格,这可能和你熟悉的所有编程语言都不一样.同时,变量名的命名须遵 ...
- LeetCode OJ:Remove Duplicates from Sorted Array II(移除数组中的重复元素II)
Follow up for "Remove Duplicates":What if duplicates are allowed at most twice? For exampl ...
- 地图之CoreLocation
1. 在Info.plist文件中添加下面两句话 NSLocationAlwaysUsageDescription —> 确定定位吗?亲 (或者改参数类型为BOOL类型 值为Y) 请求的授权, ...