我们知道,消费者有两种方式从消息中间件获取消息:

  • 推模式:消息中间件主动将消息推送给消费者
  • 拉模式:消费者主动从消息中间件拉取消息

推模式将消息提前推送给消费者,消费者必须设置一个缓冲区缓存这些消息。好处很明显,消费者总是有一堆在内存中待处理的消息,所以效率高。缺点是缓冲区可能会溢出。

拉模式在消费者需要时才去消息中间件拉取消息,这段网络开销会明显增加消息延迟,降低系统吞吐量。

选择推模式还是拉模式需要考虑使用场景。

前面 HelloWorld 例子中使用 Consumer 接口的方式是推模式。RabbitMQ 会把队列中的消息全部推送给消费者。如果删除 Sender 的 sleep 代码行,只要 Receiver 连着 hello 队列,你就会发现 hello 队列根本存不住消息,全都发送给了 Receiver,哪怕 Receiver 处理的再慢。

RabbitMQ 同时提供了拉模式,代码如下:

gordon.study.rabbitmq.helloworld.ReceiverByGet.java

public class ReceiverByGet {

    private final static String QUEUE_NAME = "hello";

    public static void main(String[] argv) throws Exception {
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("localhost");
Connection connection = factory.newConnection();
Channel channel = connection.createChannel(); channel.queueDeclare(QUEUE_NAME, false, false, false, null); while (true) {
GetResponse resp = channel.basicGet(QUEUE_NAME, true);
if (resp == null) {
System.out.println("Get Nothing!");
TimeUnit.MILLISECONDS.sleep(1000);
} else {
String message = new String(resp.getBody(), "UTF-8");
System.out.printf(" [ %2$s<===](%1$s) %3$s\n", "Receiver", QUEUE_NAME, message);
TimeUnit.MILLISECONDS.sleep(500);
}
}
}
}

代码第14行通过 basicGet 方法,主动去第一个参数指定的队列(hello队列)尝试获取一个消息,这是一个非阻塞方法,当从队列中获取消息失败时,会返回 null,成功则返回 GetResponse 实例。第二个参数 autoAck 指定消息确认模式,作用同前文 basicConsume 方法同名参数。

代码第15行判断返回为 null 的场景。当返回为 null 时一般是因为队列中无可用消息,所以需要让自己 sleep 一小段时间,以防止过于频繁地尝试获取消息。

RabbitMQ入门_03_推拉模式的更多相关文章

  1. NetMQ(四): 推拉模式 Push-Pull

    ZeroMQ系列 之NetMQ 一:zeromq简介 二:NetMQ 请求响应模式 Request-Reply 三:NetMQ 发布订阅模式 Publisher-Subscriber 四:NetMQ ...

  2. ActiveMQ基本详解与总结& 消息队列-推/拉模式学习 & ActiveMQ及JMS学习

    转自:https://www.cnblogs.com/Survivalist/p/8094069.html ActiveMQ基本详解与总结 基本使用可以参考https://www.cnblogs.co ...

  3. 消息队列-推/拉模式学习 & ActiveMQ及JMS学习

    一种分类是推和拉 . 还有一种分类是 Queue 和 Pub/Sub . 先看的这一篇:http://blog.csdn.net/heyutao007/article/details/50131089 ...

  4. RabbitMQ入门-高效的Work模式

    扛不住的Hello World模式 上篇<RabbitMQ入门-从HelloWorld开始>介绍了RabbitMQ中最基本的Hello World模型.正如其名,Hello World模型 ...

  5. RabbitMQ入门-Routing直连模式

    Hello World模式,告诉我们如何一对一发送和接收消息: Work模式,告诉我们如何多管齐下高效的消费消息: Publish/Subscribe模式,告诉我们如何广播消息 那么有没有灵活强一点的 ...

  6. 实战ZeroMQ的PUSH/PULL推拉模式

    原文地址: http://ju.outofmemory.cn/entry/235976

  7. RabbitMQ入门-Topic模式

    上篇<RabbitMQ入门-Routing直连模式>我们介绍了可以定向发送消息,并可以根据自定义规则派发消息.看起来,这个Routing模式已经算灵活的了,但是,这还不够,我们还有更加多样 ...

  8. 微博feed系统的推(push)模式和拉(pull)模式和时间分区拉模式架构探讨

    sns系统,微博系统都应用到了feed(每条微博或者sns里的新鲜事等我们称作feed)系统,不管是twitter.com或者国内的新浪微博,人人网等,在各种技术社区,技术大会上都在分享自己的feed ...

  9. RabbitMQ入门到进阶(Spring整合RabbitMQ&SpringBoot整合RabbitMQ)

    1.MQ简介 MQ 全称为 Message Queue,是在消息的传输过程中保存消息的容器.多用于分布式系统 之间进行通信. 2.为什么要用 MQ 1.流量消峰 没使用MQ 使用了MQ 2.应用解耦 ...

随机推荐

  1. SElinux以及防火墙的关闭

    [root@localhost targeted]# pwd/etc/selinux/targeted[root@localhost targeted]# getsebool -a|grep samb ...

  2. 善用缓存提高你的Spring工程效率

    欢迎查看Java开发之上帝之眼系列教程,如果您正在为Java后端庞大的体系所困扰,如果您正在为各种繁出不穷的技术和各种框架所迷茫,那么本系列文章将带您窥探Java庞大的体系.本系列教程希望您能站在上帝 ...

  3. postgresql----排序ORDER BY,分组GROUP BY,分页OFFSET&&LIMIT

    一.GROUP BY 使用GROUP BY分组查询在SELECT子句中只能出现分组字段和聚合函数,HAVING子句相当于WHERE,使用条件过滤数据. 示例1.以a,b分组查询tbl_insert表, ...

  4. javascript飞机大战-----002游戏引擎

    基本html布局 <!DOCTYPE html> <html lang="en"> <head> <meta charset=" ...

  5. toml-lang - Tom's Obvious, Minimal Language

    Tom's Obvious, Minimal Languagehttps://github.com/toml-lang/toml

  6. 什么是虚拟DOM?

    (摘抄自一篇文章,觉得这里写得非常不错,所以单独放出来,希望能对大家有帮助.)React为啥这么大?因为它实现了一个虚拟DOM(Virtual DOM).虚拟DOM是干什么的?这就要从浏览器本身讲起 ...

  7. stm8s 时钟库函数选择内部RC初始化

    //本文选择16M内部RC震荡.分频为1 即系统时钟为16M void CLK_HSICmd(FunctionalState NewState) { /* Check the parameters * ...

  8. google chrome插件开发,自己动手,丰衣足食

    因为平时上网都用chrome,但总感觉除了速度快,简洁以外总还有地方满足不了我的需要,然后找插件…后来发现,插件虽然海量但找个称心如意的也不是件容易的事儿,用在找插件的时间都能自己写一个了,于是,今年 ...

  9. cocos代码研究(9)ProgressTimer类学习笔记

    理论部分 ProgressTimer是Node的子类. 该类根据百分比来渲染显示内部的Sprite对象. 变化方向包括径向,水平或者垂直方向. 代码部分 Type getType () const获取 ...

  10. SQLite 自定义函数,聚合,排序规则

    SQLite 自定义函数,聚合,排序规则 1.使用自定义函数, 聚合以及排序规则的基本方法是使用回调函数.这些注册的函数的生命周期只存在于应用程序中, 并不存储在数据库文件中, 因此需要在每个连接建立 ...