版权声明:本文为博主原创文章,未经博主朱小厮允许不得转载。 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)的更多相关文章

  1. JMS学习(八)-ActiveMQ Consumer 使用 push 还是 pull 获取消息

    ActiveMQ是一个消息中间件,对于消费者而言有两种方式从消息中间件获取消息: ①Push方式:由消息中间件主动地将消息推送给消费者:②Pull方式:由消费者主动向消息中间件拉取消息.看一段官网对P ...

  2. 理解bootstrap的列偏移offset 和 推拉push/pull的区别?

    参考: http://www.cnblogs.com/jnslove/p/5430481.html & https://blog.csdn.net/hly_coder/article/deta ...

  3. MongoDB之$关键字及$修改器$set $inc $push $pull $pop

    一.查询中常见的  等于   大于  小于  大于等于  小于等于 等于:用':' 大于:用'$gt' 小于:用'$lt' 大于等于:用'$gte' 小于等于:用'$lte' MongoDB的操作就是 ...

  4. MongoDB 之 $关键字 及 $修改器 $set $inc $push $pull $pop MongoDB - 4

    我们在之前的 MongoDB 之 手把手教你增删改查 MongoDB - 2 中提到过 $set 这个系统关键字,用来修改值的对吧 但是MongoDB中类似这样的关键字有很多, $lt $gt $lt ...

  5. git push/pull时总需要输入用户名密码的解决方案

    在提交项目代码或者拉代码的时候,git会让你输入用户名密码,解决方案:(我们公司用的是gitlab) 执行git config --global credential.helper store命令 然 ...

  6. 4,MongoDB 之 $关键字 及 $修改器 $set $inc $push $pull $pop MongoDB

    MongoDB中的关键字有很多, $lt $gt $lte $gte 等等,这么多我们也不方便记,这里我们说说几个比较常见的 一.查询中常见的 等于 大于 小于 大于等于 小于等于 等于 : 在Mon ...

  7. Push pull, open drain circuit, pull up, pull down resistor

    Push pull 就以下面這個 電路來說, 因為沒有 pull up resistor, 所以 output voltage 由 low 往 high 的速度會較快. 有兩個電晶體,一個on,一個 ...

  8. MongoDB之$关键字,以及$修饰器$set,$inc,$push,$pull,$pop

    一.查询中常见的 等于 大于 小于 大于等于 小于等于 等于:在MongoDB中,什么字段等于什么值就是" : ",比如 "name":"路飞学城&q ...

  9. 2.每人自己建立一个HelloWorld项目,练习使用git的add/commit/push/pull/fetch/clone等基本命令。比较项目的新旧版本的差别。答题人:张立鹏

    第1步:创建SSH Key.在用户主目录下,看看有没有.ssh目录,如果有,再看看这个目录下有没有id_rsa和id_rsa.pub这两个文件,如果已经有了,可直接跳到下一步.如果没有,打开Shell ...

随机推荐

  1. 什么时候需要用super

    1.子类构造函数调用父类构造函数用super 2.子类重写(覆盖)父类方法后,若想调用父类中被重写的方法,用super 3.未被重写的方法可以直接调用.

  2. PHP面向对象程序设计之接口(interface)

    接口(interface)是抽象方法和静态常量定义的集合.接口是一种特殊的抽象类,这种抽象类中只包含抽象方法和静态常量. 为什么说接口是一种特殊的抽象类呢?如果一个抽象类里面的所有的方法都是抽象方法, ...

  3. bzoj 3479: [Usaco2014 Mar]Watering the Fields

    3479: [Usaco2014 Mar]Watering the Fields Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 174  Solved ...

  4. [mongodb] WiredTiger Storage Engine

    今天看了mongodb的官方文档中的WiredTiger Storage Engine ,说说我对WiredTiger Storage Engine 的理解! 在mongodb3.2版本以后,wire ...

  5. HDU 5703

    题意:给你一个数n,问将n分为正整数和的方案数.如n=3共四种,1 1 1 , 1 2 , 2 1 ,3 . 思路:隔板法,n个1,有n-1个空位,每个空位可以选择是否插入隔板,插入k(0<=k ...

  6. Effective C++ 条款01:视C++为一个语言联邦

    四个次语言 C Object-Oriented C++ Template C++ STL

  7. Android中获取屏幕高度和宽度

    有时我们需要获取当前屏幕的高度和宽度,只需要在一个Activity的onCreate()方法中写上如下代码即可: //定义DisplayMetrics 对象 DisplayMetrics metric ...

  8. Spring -- spring整合struts2

    1. 概述 spring和struts整合: 1.创建web程序 2.引入struts2类库. 3.创建HelloWorldAction package cn.itcast.struts2.actio ...

  9. java 实现Serv-U FTP 和 SFTP 上传 下载

    两种ftp使用java的实现方式 ,代码都已测试 第一种:Serv-U FTP 先决条件: 1.Serv-U FTP服务器搭建成功. 2.jar包需要:版本不限制 <!--ftp上传需要的jar ...

  10. 支付宝VIE的罪与罚

    http://tech.ifeng.com/special/tusimple/alibaba/#_www_dt2   雅虎的杨致远.软银的孙正义,都曾是马云阿里巴巴创业路上的贵人,也都曾是相互信任的朋 ...