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

前言

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

上文的工作队列模式是直接在生产者与消费者里声明好一个队列,这种情况下消息只会对应同类型的消费者。

显然这种只处理同种类型的消息是有弊端的。

举个用户注册的列子

门户网站,用户在注册完后一般都会发送消息通知用户注册成功(失败)。

如果在一个系统中,用户注册信息有邮箱、手机号,那么在注册完后会向邮箱和手机号都发送注册完成信息(假设都发送)。

利用 MQ 实现业务异步处理,如果是用工作队列的话,就会声明一个注册信息队列。注册完成之后生产者会向队列提交一条注册数据,消费者取出数据同时向邮箱以及手机号发送两条消息。但是实际上邮箱和手机号信息发送实际上是不同的业务逻辑,不应该放在一块处理。

这个时候就可以利用发布/订阅模式将消息发送到转换机(EXCHANGE),声明两个不同的队列(邮箱、手机),并绑定到交换机。这样生产者只需要发布一次消息,两个队列都会接收到消息发给对应的消费者,大致如下图所示。

在应用中,只需要简单的将队列绑定到交换机上。一个发送到交换机的消息都会被转发到与该交换机绑定的所有队列上。很像子网广播,每台子网内的主机都获得了一份复制的消息。

文章目录

文章目录

      • 前言
        • 举个用户注册的列子
      • 文章目录
      • 1. 什么是发布订阅模式
      • 2. 代码部分
        • 2.1 生产者
        • 2.2 邮件消费者
        • 2.3 短信消费者
        • 2.4 运行截图
      • 3. 总结

1. 什么是发布订阅模式

简单解释就是,可以将消息发送给不同类型的消费者。做到发布一次,消费多个。下图取自于官方网站(RabbitMQ)的发布/订阅模式的图例:

P 表示为生产者、 X 表示交换机、C1C2 表示为消费者,红色表示队列。

下面代码部分会展示邮件、短信的例子,通过绑定到一个交换机,但是

2. 代码部分

2.1 生产者

public class ProducerFanout {private static final String EXCHANGE_NAME = "fanout_exchange";public static void main(String[] args) throws IOException, TimeoutException {/** 1.创建新的连接 */Connection connection = MQConnectionUtils.newConnection();/** 2.创建通道 */Channel channel = connection.createChannel();/** 3.绑定的交换机 参数1交互机名称 参数2 exchange类型 */channel.exchangeDeclare(EXCHANGE_NAME, "fanout");/** 4.发送消息 */for (int i = 0; i < 10; i++){String message = "用户注册消息:" + i;System.out.println("[send]:" + message);//发送消息channel.basicPublish(EXCHANGE_NAME, "", null, message.getBytes("utf-8"));try {Thread.sleep(5 * i);} catch (InterruptedException e) {e.printStackTrace();}}/** 5.关闭通道、连接 */channel.close();connection.close();/** 注意:如果消费没有绑定交换机和队列,则消息会丢失 */}}

代码补充,channel.basicPublish(EXCHANGE_NAME, “”, null, message.getBytes(“utf-8”)); 其中第二个参数为空类似于表示全局广播,只要绑定到该队列上的消费者理论上是都可以收到的。

2.2 邮件消费者

public class ConsumerEmailFanout {private static final String QUEUE_NAME = "consumerFanout_email";private static final String EXCHANGE_NAME = "fanout_exchange";public static void main(String[] args) throws IOException, TimeoutException {System.out.println("邮件消费者启动");/* 1.创建新的连接 */Connection connection = MQConnectionUtils.newConnection();/* 2.创建通道 */Channel channel = connection.createChannel();/* 3.消费者关联队列 */channel.queueDeclare(QUEUE_NAME, false, false, false, null);/* 4.消费者绑定交换机 参数1 队列 参数2交换机 参数3 routingKey */channel.queueBind(QUEUE_NAME, EXCHANGE_NAME, "");DefaultConsumer consumer = new DefaultConsumer(channel) {@Overridepublic void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body)throws IOException {String msg = new String(body, "UTF-8");System.out.println("消费者获取生产者消息:" + msg);}};/* 5.消费者监听队列消息 */channel.basicConsume(QUEUE_NAME, true, consumer);}}

代码补充, channel.queueBind(QUEUE_NAME, EXCHANGE_NAME, “”); 中第三个参数置为空时,可以接收到生产者所有的消息(生产者 routingKey 参数为空时)。

2.3 短信消费者

public class ConsumerSMSFanout {private static final String QUEUE_NAME = "ConsumerFanout_sms";private static final String EXCHANGE_NAME = "fanout_exchange";public static void main(String[] args) throws IOException, TimeoutException {System.out.println("短信消费者启动");/* 1.创建新的连接 */Connection connection = MQConnectionUtils.newConnection();/* 2.创建通道 */Channel channel = connection.createChannel();/* 3.消费者关联队列 */channel.queueDeclare(QUEUE_NAME, false, false, false, null);/* 4.消费者绑定交换机 参数1 队列 参数2交换机 参数3 routingKey */channel.queueBind(QUEUE_NAME, EXCHANGE_NAME, "");DefaultConsumer consumer = new DefaultConsumer(channel) {@Overridepublic void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body)throws IOException {String msg = new String(body, "UTF-8");System.out.println("消费者获取生产者消息:" + msg);}};/* 5.消费者监听队列消息 */channel.basicConsume(QUEUE_NAME, true, consumer);}}

代码补充, channel.queueBind(QUEUE_NAME, EXCHANGE_NAME, “”); 中第三个参数置为空时,可以接收到生产者所有的消息(生产者 routingKey 参数为空时)

2.4 运行截图

先运行两个消费者,再运行生产者。如果没有提前将队列绑定到交换机,那么直接运行生产者的话,消息是不会发到任何队列里的。

生产者

短信消费者

邮件消费者

3. 总结

首先相对于工作模式,发布订阅模式引入了交换机的概念,相对其类型上更加灵活广泛一些。通过上文我们可以总结如下:

1.生产者不是直接操作队列,而是将数据发送给交换机,由交换机将数据发送给与之绑定的队列。从不加特定参数的运行结果中可以看到,两种类型的消费者(email,sms)都收到相同数量的消息。

  1. 必须声明交换机,并且设置模式:channel.exchangeDeclare(EXCHANGE_NAME, “fanout”),其中 fanout 指分发模式(将每一条消息都发送到与交换机绑定的队列)。

  2. 队列必须绑定交换机:channel.queueBind(QUEUE_NAME, EXCHANGE_NAME, “”);

生产者发送消息到交换机,多个消费者声明多个队列,与交换机进行绑定,队列中的消息可以被所有消费者消费,类似于QQ群消息

案例代码:https://www.lanzous.com/i5ydu6d

我创建了一个java相关的公众号,用来记录自己的学习之路,感兴趣的小伙伴可以关注一下微信公众号哈:niceyoo

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/414189.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

javafx HBOX按钮右对齐

<HBox spacing"20" alignment"CENTER_LEFT"> <!---关键在这里----><HBox HBox.hgrow"ALWAYS"></HBox><JFXButton prefWidth"100" fx:id"dialogCommitButton" prefHeight"40" textAlig…

景山公园

转载于:https://www.cnblogs.com/optor/p/8928938.html

RabbitMQ六种队列模式-工作队列模式

前言 RabbitMQ六种队列模式-简单队列 RabbitMQ六种队列模式-工作队列 [本文] RabbitMQ六种队列模式-发布订阅 RabbitMQ六种队列模式-路由模式 RabbitMQ六种队列模式-主题模式 上文我们了解了 RabbitMQ 六种队列模式中的简单队列&#xff0c;代码也是非常的简单&#xff0c;比较…

RabbitMQ六种队列模式-简单队列模式

前言 RabbitMQ六种队列模式-简单队列 [本文] RabbitMQ六种队列模式-工作队列 RabbitMQ六种队列模式-发布订阅 RabbitMQ六种队列模式-路由模式 RabbitMQ六种队列模式-主题模式 在官网的教程中&#xff0c;描述了如上六类工作队列模式&#xff1a; 简单队列模式&#xff1a;最简…

工作290:重置新增的mode

/*4 GY定义 找到该组件下面的add方法*/add() {/* 5GY定义 给当前属性下面的title赋值*/this.title "新增";/*重置新增的mode*/this.mode[]this.show();this.IsShowtrue;this.attrthis.viewMode false;this.approveMode false/* 7GY定义 给当前的form赋值 并进行对…

串口数据字节位的理解

# STM32F4xx系列的MCU的UART数据字节组成如下图 # 发送数据做如下图示&#xff0c;data byte MSB 与 Parity 重合 # 先刨去 Parity bit&#xff0c;分析 LSB ~ MSB 的纯数据&#xff1a; > 假定数据中的 ‘1’ 个数为奇数&#xff0c;偶校验&#xff1a;Parity ‘1’&#…

RabbitMQ消息确认机制

文章目录1. 事务机制2. Confirm模式2.1 生产者2.1.1 普通Confirm模式2.1.2 批量Confirm模式2.1.3 异步Confirm模式2.2 消费者3. 其他消费者如何确保消息一定能够消费成功呢&#xff1f;由于在前面工作队列模式里面我们了解了应答模式&#xff0c;所以我们可以很自信的回答如上题…

RabbitMQ消息幂等性问题

文章目录1. 什么是幂等性&#xff1f;1.1 消息队列的幂等性1.2 模拟重试机制1.2.1 生产者代码1.2.2 消费者代码1.2.3 消费者 application.yml 配置2. 如何保证消息幂等性&#xff0c;不被重复消费&#xff1f;解决方法1. 什么是幂等性&#xff1f; 在编程中一个幂等操作的特点是…

Centos安装JDK(java环境)

王小私下问我 centos 中 jdk 怎么安装呀&#xff0c;所以再次整理了这篇基础环境搭建的文章。 1、创建java目录2、下载上传jdk3、解压jdk4、配置环境变量 1、创建java目录 首先我们创建java的安装目录 cd /usrmkdir javacd java 2、下载上传jdk 我们如上在 usr 目录下创建了 ja…

工作288:根据时间戳处理接口

<template><div class"table-list-page"><div class"query-area"><el-date-pickerv-model"value1"type"daterange"range-separator"至"start-placeholder"开始日期"end-placeholder"结…

Centos7安装MySQL(多图)

文章目录一、在线安装1、替换网易yum源2、清理缓存3、下载rpm文件4、安装MySQL数据库二、本地安装1、上传MySQL安装包2、安装依赖的程序包3、卸载mariadb程序包4、安装MySQL程序包5、修改MySQL目录权限6、初始化MySQL三、启动MySQL1.1、在线安装方式启动MySQL1.2、本地安装方式…

lower_case_table_names=1 启动报错 mysql8.0

本文为采集文章&#xff0c;主博客地址&#xff1a;https://www.cnblogs.com/niceyoo 我们知道在 Linux 环境下默认是区分大小写的&#xff0c;所以我们需要改变这种默认方式&#xff0c;经过网上各种搜索后&#xff0c;基本就是清一色的修改 lower_case_table_names&#xff0…

工作292:修改父子组件传值错误

[Vue warn]: Missing required prop: “title” 在写vue项目中&#xff0c;在子组件中通过props传值的时候&#xff0c;在父组件中没有定义的话就会看到类似的报错&#xff0c; 这个意思是calendar这个组件中通过props传递一个title属性给父组件&#xff0c;并且title属性是必…

MacOS下IDEA设置智能提示不区分大小写

本文只针对&#xff0c;IDEA-2019.2.3版本 目录地址&#xff1a; Edit -> General -> Code Completion -> Match case -> 勾选去掉 截图如下&#xff1a;

博客园文章方块背景格式

有小伙伴问到方格背景的问题&#xff0c;所以写一篇文章记录我的博客园文章背景是如何制作的。 一、辅助网站1. 一键排版2. 代码主题3. 复制二、 图床设置 一、辅助网站 辅助网址&#xff1a;Md2All 作者提供了一篇帮助文章&#xff1a;玩转公众号Markdown 其实大致看完辅助网址…

day02 pycharm 安装

pycharm 是一款现在比较主流的辅助开发软件 不选择虚拟 所以选择Existing现有的 安装后只需打开当前窗口 默认的 不需要大家新的窗口 使用鼠标滚轮来实现放大缩小 使用debug模式测试代码 转载于:https://www.cnblogs.com/zhaohongyu6688/p/8962253.html

eclipse启动项目

今天做的任务不多&#xff0c;没有自己写代码&#xff0c;上午看了些文章&#xff0c;下午我司后台给配了配项目环境&#xff0c;全装C盘了。。以后有我好受的。。 看着后台操作&#xff0c;修改了N多配置&#xff0c;tomcat、redis、zkServer.、Nginx&#xff0c;navcat、ecli…

如何写一份优秀的java程序员简历

背景&#xff1a;进入第一家公司已经工作将近两年了&#xff0c;其中闲了一年&#xff0c;在准备自己的简历的时候&#xff0c;有种江郎才尽的感觉&#xff0c;不知道怎么写&#xff0c;看来平时还是要多积累多熟悉。 PS&#xff1a;这里面的分享看完还是很受用的。 简历看得比…

macos -bash: yarn: command not found/-bash: cnpm: command not found

博客主要更新地址&#xff1a;?https://www.cnblogs.com/niceyoo -bash: cnpm: command not found -bash: yarn: command not found -bash: xxxx: command not found 如上yarn/cnpm皆通用&#xff0c;前提是安装成功后报这个错误哈&#xff01; Error: EACCES: permission den…

部署项目到jetty

一、打包项目 1、在pom.xml中添加以下依赖 <dependency><groupId>org.mortbay.jetty</groupId><artifactId>jetty-plus</artifactId><version>7.0.0.pre5</version><scope>provided</scope> </dependency> <de…