订阅模型分类

在之前的模式中,我们创建了一个工作队列。 工作队列背后的假设是:每个任务只被传递给一个工作人员。 在这一部分,我们将做一些完全不同的事情 - 我们将会传递一个信息给多个消费者。 这种模式被称为“发布/订阅”。

订阅模型示意图:

解读:

1、1个生产者,多个消费者

2、每一个消费者都有自己的一个队列

3、生产者没有将消息直接发送到队列,而是发送到了交换机

4、每个队列都要绑定到交换机

5、生产者发送的消息,经过交换机到达队列,实现一个消息被多个消费者获取的目的

X(Exchanges):交换机一方面:接收生产者发送的消息。另一方面:知道如何处理消息,例如递交给某个特别队列、递交给所有队列、或是将消息丢弃。到底如何操作,取决于Exchange的类型。

Exchange类型有以下几种:

Fanout:广播,将消息交给所有绑定到交换机的队列Direct:定向,把消息交给符合指定routing key 的队列 Topic:通配符,把消息交给符合routing pattern(路由模式) 的队列

我们这里先学习

Fanout:即广播模式

Exchange(交换机)只负责转发消息,不具备存储消息的能力,因此如果没有任何队列与Exchange绑定,或者没有符合路由规则的队列,那么消息会丢失!

订阅模型-Fanout

Fanout,也称为广播。

流程图:

在广播模式下,消息发送流程是这样的:

  • 1) 可以有多个消费者

  • 2) 每个消费者有自己的queue(队列)

  • 3) 每个队列都要绑定到Exchange(交换机)

  • 4) 生产者发送的消息,只能发送到交换机,交换机来决定要发给哪个队列,生产者无法决定。

  • 5) 交换机把消息发送给绑定过的所有队列

  • 6) 队列的消费者都能拿到消息。实现一条消息被多个消费者消费

生产者

两个变化:

  • 1) 声明Exchange,不再声明Queue

  • 2) 发送消息到Exchange,不再发送到Queue

public class Send {private final static String EXCHANGE_NAME = "fanout_exchange_test";public static void main(String[] argv) throws Exception {// 获取到连接Connection connection = ConnectionUtil.getConnection();// 获取通道Channel channel = connection.createChannel();// 声明exchange,指定类型为fanoutchannel.exchangeDeclare(EXCHANGE_NAME, "fanout");// 消息内容String message = "Hello everyone";// 发布消息到Exchangechannel.basicPublish(EXCHANGE_NAME, "", null, message.getBytes());System.out.println(" [生产者] Sent '" + message + "'");channel.close();connection.close();}
}

消费者1

public class Recv {private final static String QUEUE_NAME = "fanout_exchange_queue_1";private final static String EXCHANGE_NAME = "fanout_exchange_test";public static void main(String[] argv) throws Exception {// 获取到连接Connection connection = ConnectionUtil.getConnection();// 获取通道Channel channel = connection.createChannel();// 声明队列channel.queueDeclare(QUEUE_NAME, false, false, false, null);// 绑定队列到交换机channel.queueBind(QUEUE_NAME, EXCHANGE_NAME, "");// 定义队列的消费者DefaultConsumer consumer = new DefaultConsumer(channel) {// 获取消息,并且处理,这个方法类似事件监听,如果有消息的时候,会被自动调用@Overridepublic void handleDelivery(String consumerTag, Envelope envelope, BasicProperties properties,byte[] body) throws IOException {// body 即消息体String msg = new String(body);System.out.println(" [消费者1] received : " + msg + "!");}};// 监听队列,自动返回完成channel.basicConsume(QUEUE_NAME, true, consumer);}
}

要注意代码中:队列需要和交换机绑定

消费者2

public class Recv2 {private final static String QUEUE_NAME = "fanout_exchange_queue_2";private final static String EXCHANGE_NAME = "fanout_exchange_test";public static void main(String[] argv) throws Exception {// 获取到连接Connection connection = ConnectionUtil.getConnection();// 获取通道Channel channel = connection.createChannel();// 声明队列channel.queueDeclare(QUEUE_NAME, false, false, false, null);// 绑定队列到交换机channel.queueBind(QUEUE_NAME, EXCHANGE_NAME, "");// 定义队列的消费者DefaultConsumer consumer = new DefaultConsumer(channel) {// 获取消息,并且处理,这个方法类似事件监听,如果有消息的时候,会被自动调用@Overridepublic void handleDelivery(String consumerTag, Envelope envelope, BasicProperties properties,byte[] body) throws IOException {// body 即消息体String msg = new String(body);System.out.println(" [消费者2] received : " + msg + "!");}};// 监听队列,手动返回完成channel.basicConsume(QUEUE_NAME, true, consumer);}
}

测试

我们运行两个消费者,然后发送1条消息:

发布订阅之fanout相关推荐

  1. RabbitMQ 发布/订阅

    我们会做一些改变,就是把一个消息发给多个消费者,这种模式称之为发布/订阅(类似观察者模式). 为了验证这种模式,我们准备构建一个简单的日志系统.这个系统包含两类程序,一类程序发动日志,另一类程序接收和 ...

  2. RabbitMQ(三) ——发布订阅

    RabbitMQ(三) --发布订阅 (转载请附上本文链接--linhxx) 一.概述 RabbitMQ的发布订阅(Publish/Subscribe),其将生产者和消费者进一步解耦,生产者生产消息后 ...

  3. [译]RabbitMQ教程C#版 - 发布订阅

    先决条件 本教程假定RabbitMQ已经安装,并运行在localhost标准端口(5672).如果你使用不同的主机.端口或证书,则需要调整连接设置. 从哪里获得帮助 如果您在阅读本教程时遇到困难,可以 ...

  4. RabbitMQ系列教程之三:发布\/订阅(Publish\/Subscribe)

    在前一个教程中,我们创建了一个工作队列.工作队列背后的假设是每个任务会被交付给一个[工人].在这一部分我们将做一些完全不同的事情--我们将向多个[消费者]传递信息.这种模式被称为"发布/订阅 ...

  5. RabbitMQ入门教程——发布/订阅

    什么是发布订阅 发布订阅是一种设计模式定义了一对多的依赖关系,让多个订阅者对象同时监听某一个主题对象.这个主题对象在自身状态变化时,会通知所有的订阅者对象,使他们能够自动更新自己的状态. 为了描述这种 ...

  6. RabbitMQ六种队列模式-发布订阅模式

    前言 RabbitMQ六种队列模式-简单队列 RabbitMQ六种队列模式-工作队列 RabbitMQ六种队列模式-发布订阅 [本文] RabbitMQ六种队列模式-路由模式 RabbitMQ六种队列 ...

  7. 【转】RabbitMQ六种队列模式-3.发布订阅模式

    前言 RabbitMQ六种队列模式-简单队列 RabbitMQ六种队列模式-工作队列 RabbitMQ六种队列模式-发布订阅 [本文] RabbitMQ六种队列模式-路由模式 RabbitMQ六种队列 ...

  8. RabbitMQ实例教程:发布/订阅者消息队列

    消息交换机(Exchange) RabbitMQ消息模型的核心理念是生产者永远不会直接发送任何消息给队列,一般的情况生产者甚至不知道消息应该发送到哪些队列. 相反的,生产者只能发送消息给交换机(Exc ...

  9. 上下文管理、redis发布订阅、RabbitMQ发布订阅、SQLAlchemy

    一.上下文管理 import contextlib @contextlib.contextmanager def work_state(state_list,worker_thread):state_ ...

最新文章

  1. 神奇的10个人10个帽子的问题
  2. JS 取消冒泡事件 兼容火狐IE
  3. JS排序算法之插入排序
  4. tmux命令启动MySQL_tmux启动脚本
  5. 我们找阿里云资深技术专家李响聊了聊开源和云原生
  6. java短横线转驼峰_Java后端常备的开发规范
  7. 【转】C# split 几种使用方法
  8. linux下网络监听与发送数据包的方法(即libpcap、libnet两种类库的使用方法)
  9. 畅游互联的API接口如何对接到自己的网站上?
  10. 频率与振幅的关系图怎么画_手拉手模型怎么画?5步教你分分钟完成模型图
  11. windows平台上编写的python无法在unix_在Windows平台上编写的Python程序无法在Unix平台运行?...
  12. c++课程设计(水)
  13. 基于SSM的电脑商城(源码)
  14. 测试用例方法-等价类划分
  15. 洛谷试炼场---提高历练地2
  16. 微信小程序 一键保存视频到手机相册功能(视频来源为链接)
  17. Lipschitz条件
  18. 3-2-1 程序控制结构-while循环结构-多次求解一元二次方程?-while循环常见错误?
  19. 域名劫持定义及原理、域名被劫持解决办法有那些
  20. Jmeter实现多用户压测

热门文章

  1. 软件工程课堂作业——寻找“水王”
  2. Developer Express 中Gridcontrol获取选中行单元格的值
  3. 使用SQL Server 2005 Report Builder
  4. asp.net中生命周期的浅析
  5. CSS 布局与“仓库管理”的关系
  6. datax源码阅读一:python文件
  7. 为什么静态成员、静态方法中不能用this和super关键字
  8. BZOJ2568 [国家集训队2012]比特集合
  9. (旧)子数涵数·Flash——遮罩动画
  10. 关于《在Windows与.NET平台上的持续交付实践》的问答录