RabbitMQ学习笔记(一)RabbitMQ部署、5种队列模型

文章目录

  • 1 认识MQ
    • 1.1 同步和异步通讯
      • 1.1.1 同步通讯
      • 1.1.2 异步通讯
    • 1.2 技术对比
  • 2 RabbitMQ入门
    • 2.1 RabbitMQ单机部署
    • 2.2 RabbitMQ基本结构
    • 2.3 RabbitMQ队列模型
      • 2.3.1 简单队列模型(Simple Queue Model)
      • 2.3.2 工作队列模型(Work Queue Model)
      • 2.3.3 发布/订阅模型(Publish/Subscribe Model)
        • 2.3.3.1 广播模型(Fanout)
        • 2.3.3.2 定向模型(Direct)
        • 2.3.3.3 通配符模型(Topic)
    • 2.4 使用案例
      • 2.4.1 Publisher实现
      • 2.4.2 Consumer实现

1 认识MQ

1.1 同步和异步通讯

微服务间的通讯有同步和异步两种方式:

  • 同步通讯:就像打电话,需要实时响应;
  • 异步通讯:就像发邮件,不需要马上回复。

两种方式各有优劣,打电话可以立即得到响应,但是却不能跟多个人同时通话;发邮件可以同时与多个人收发邮件,但是往往响应会有延迟。

1.1.1 同步通讯

微服务之间采用Feign调用就属于同步方式,调用可以实时得到结果,但存在下面的问题:

  • 耦合度高:每次加入新的需求,都要修改原来的代码;
  • 性能下降:调用者需要等待服务提供者的响应,如果调用链过长则响应时间等于各个调用时间之和;
  • 资源浪费:调用者在等待响应时,不能释放请求所占用的资源,高并发场景下会极度浪费系统资源;
  • 级联失败:如果服务提供者出现问题,则调用者也会出现问题,甚至导致集群故障。

1.1.2 异步通讯

异步调用则可以避免上述问题。以购买商品为例,用户支付成功后需要调用订单服务完成订单状态修改,调用物流服务从仓库减库存并发货。

在该案例中,支付服务是事件发布者(Publisher),在支付成功后只需要发布一个支付成功的事件(Event),事件中带上订单id。而订单服务和物流服务是事件订阅者(Consumer),监听支付成功的事件,监听到支付成功事件后完成自己业务即可。

如上图所示,为了解除事件发布者与订阅者之间的耦合,两者并不是直接通信,而是有一个中间人(Broker)。发布者发布事件到Broker,而不关心谁来订阅事件;订阅者从Broker订阅事件,也不关心是谁发来的消息。

Broker就像数据总线一样,所有的服务要接收数据和发送数据都在这个总线上。这个总线就像协议一样,让服务间的通讯变得标准和可控。

异步调用的优点:

  • 吞吐量提升:无需等待订阅者处理完成,响应更快速;
  • 故障隔离:服务没有直接调用,不存在级联失败问题;
  • 资源释放:调用间没有阻塞,不会造成无效的资源占用;
  • 耦合度极低:每个服务都可以灵活插拔,可替换;
  • 流量削峰:不管发布事件的流量波动多大,都由Broker接收,订阅者可以按照自己的速度去处理事件。

异步调用的缺点:

  • 架构复杂:业务没有明显的流程线,不好管理;
  • 依赖性强:需要依赖于Broker的可靠、安全、性能。

现在开源软件或云平台上Broker的软件是非常成熟的,比较常见的一种就是MQ技术。

1.2 技术对比

MQ(MessageQueue),即消息队列,也就是存放消息的队列,一般充当事件驱动架构中的Broker。

比较常见的MQ实现:

  • ActiveMQ
  • RabbitMQ
  • RocketMQ
  • Kafka
RabbitMQActiveMQRocketMQKafka
公司/社区RabbitApache阿里Apache
开发语言ErlangJavaJavaScala&Java
协议支持AMQP,XMPP,
SMTP,STOMP
OpenWire,STOMP,
REST,XMPP,AMQP
自定义协议自定义协议
可用性一般
单机吞吐量一般非常高
消息延迟微秒级毫秒级毫秒级毫秒以内
消息可靠性一般一般

根据以上表格,选择哪种MQ的策略可以参考如下:

  • 追求可用性:Kafka、 RocketMQ 、RabbitMQ
  • 追求可靠性:RabbitMQ、RocketMQ
  • 追求吞吐能力:RocketMQ、Kafka
  • 追求消息低延迟:RabbitMQ、Kafka

2 RabbitMQ入门

2.1 RabbitMQ单机部署

在Centos7虚拟机中使用Docker来单机部署RabbitMQ:

  • 1)在线拉取镜像
docker pull rabbitmq:3-management

  • 2)创建并运行RabbitMQ容器
docker run \-e RABBITMQ_DEFAULT_USER=rabbitmq \-e RABBITMQ_DEFAULT_PASS=123321 \--name rmq \--hostname mq1 \-p 15672:15672 \-p 5672:5672 \-d \rabbitmq:3-management

  • 3)在浏览器访问http://192.168.146.129:15672

输入账号密码:

至此,单机RabbitMQ部署完毕。

2.2 RabbitMQ基本结构

如上图所示,RabbitMQ中包含如下一些角色:

  • Publisher:生产者
  • Consumer:消费者
  • Exchange:交换机,负责消息路由
  • Queue:队列,存储消息
  • VirtualHost:虚拟主机,不同租户的exchange、queue、消息的隔离

2.3 RabbitMQ队列模型

2.3.1 简单队列模型(Simple Queue Model)

简单队列模型是最基础的RabbitMQ模型。它包括单个生产者单个消费者。生产者将消息发送到一个队列中,然后消费者从这个队列中读取消息并处理。

这种模式实现简单,易于理解和部署;但不支持并发消费,不支持多个消费者共同消费一个队列,因为一旦消息被一个消费者接收,它就会从队列中删除。因此,这种模式适用于单生产者和单消费者之间的点对点通信。

2.3.2 工作队列模型(Work Queue Model)

工作队列模型允许多个消费者协同地从一个队列中接收、处理和分发消息。在这种模型中,消息在不同的消费者之间进行负载均衡,被平均分配给不同的消费者。同时,当一个消费者正在处理一个消息时,它不能接收新的消息。

这种模型支持多个消费者同时处理同一个队列中的消息,实现了并发消费,具有更高的消息吞吐量。

2.3.3 发布/订阅模型(Publish/Subscribe Model)

2.3.3.1 广播模型(Fanout)

广播模型允许一个生产者向多个消费者广播一条消息。在这种模型中,生产者将消息发送到一个交换机(图中的X)中,然后这个交换机将消息路由到所有与之绑定的队列。每个队列对应一个消费者,可以独立地处理这个队列中的消息。

这种模型适用于将一条消息发送给多个消费者的场景,例如事件通知或新闻发布。

2.3.3.2 定向模型(Direct)

定向模型允许生产者根据路由将消息发送到指定的队列中。在这种模型中,生产者将消息发送到一个交换机中,交换机会将消息路由到与它所绑定的、且路由完全匹配的队列中。每个队列对应一个消费者,可以独立地处理这个队列中的消息。

这种模型适用于根据某些特定属性或条件将消息路由到指定队列的场景,例如日志记录或按优先级处理任务。

2.3.3.3 通配符模型(Topic)

通配符模型是定向模型的扩展实现。在这种模型中,允许使用通配符匹配来匹配路由。生产者将消息发送到一个交换机中,交换机会将消息路由到与它所绑定的、且与通配符匹配的路由所指向的队列中。每个队列对应一个消费者,可以独立地处理这个队列中的消息。

这种模型适用于根据消息内容将消息路由到不同队列的场景,例如按标签或关键字分发和处理不同的任务。

2.4 使用案例

下面基于简单队列模型实现一个使用案例,该案例中包含三个角色,分别是:

  • Publisher:消息发布者,将消息发送到队列Queue
  • Queue:消息队列,负责接受并缓存消息
  • Consumer:订阅队列,处理队列中的消息

创建一个maven项目,引入RabbitMQ依赖:

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-amqp</artifactId>
</dependency>

2.4.1 Publisher实现

@Test
public void testSendMessage() throws IOException, TimeoutException {// 1.建立连接ConnectionFactory factory = new ConnectionFactory();factory.setHost("192.168.146.129");factory.setPort(5672);factory.setVirtualHost("/");factory.setUsername("rabbitmq");factory.setPassword("123321");Connection connection = factory.newConnection();// 2.创建通道ChannelChannel channel = connection.createChannel();// 3.创建队列String queueName = "simple.queue";channel.queueDeclare(queueName, false, false, false, null);// 4.发送消息String message = "hello, rabbitmq!";channel.basicPublish("", queueName, null, message.getBytes());System.out.println("发送消息成功:【" + message + "】");// 5.关闭通道和连接channel.close();connection.close();
}

执行以上单元测试,控制台打印结果如下:

此时在RabbotMQ管理页面可以看到这条消息:

2.4.2 Consumer实现

@Test
public void testGetMessage() throws IOException, TimeoutException {// 1.建立连接ConnectionFactory factory = new ConnectionFactory();factory.setHost("192.168.146.129");factory.setPort(5672);factory.setVirtualHost("/");factory.setUsername("rabbitmq");factory.setPassword("123321");Connection connection = factory.newConnection();// 2.创建通道ChannelChannel channel = connection.createChannel();// 3.创建队列String queueName = "simple.queue";channel.queueDeclare(queueName, false, false, false, null);// 4.订阅消息channel.basicConsume(queueName, true, new DefaultConsumer(channel){@Overridepublic void handleDelivery(String consumerTag, Envelope envelope,AMQP.BasicProperties properties, byte[] body) throws IOException {// 5.处理消息String message = new String(body);System.out.println("接收到消息:【" + message + "】");}});System.out.println("等待接收消息。。。。");
}

执行以上单元测试,控制台打印结果如下:

本节完,更多内容请查阅分类专栏:微服务学习笔记

感兴趣的读者还可以查阅我的另外几个专栏:

  • SpringBoot源码解读与原理分析
  • MyBatis3源码深度解析
  • Redis从入门到精通
  • MyBatisPlus详解
  • SpringCloud学习笔记

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

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

相关文章

visual studio打包qt算子时,只生成dll没有生成lib等文件

问题&#xff1a;在visual studio配置了qt项目&#xff0c;并打包成dll&#xff0c;原则上会生成一堆文件&#xff0c;包括dll,lib等文件。 解决办法&#xff1a; 挨个右击源代码的所有头文件-》属性-》项类型。改成qt头文件形式&#xff0c;如下。

事务详讲(本地及分布式)

本地事务在分布式的问题: 因为在分布式服务中,难免一个接口中会有很多调用远程服务的情况,这个就非常容易出现问题,以下是一个详细的例子: 例如,你为了保证事物的一致性等要求,所以,你方法上只写了Transactional,但你的业务中又需要调用其他微服务的方法(Feign),这时就容易出现…

【机器学习】Qwen1.5-14B-Chat大模型训练与推理实战

目录 一、引言 二、模型简介 2.1 Qwen1.5 模型概述 2.2 Qwen1.5 模型架构 三、训练与推理 3.1 Qwen1.5 模型训练 3.2 Qwen1.5 模型推理 四、总结 一、引言 Qwen是阿里巴巴集团Qwen团队的大语言模型和多模态大模型系列。现在&#xff0c;大语言模型已升级到Qwen1.5&…

使用 Scapy 库编写 ICMP 重定向攻击脚本

一、介绍 ICMP重定向攻击&#xff08;ICMP Redirect Attack&#xff09;是一种网络攻击&#xff0c;攻击者通过发送伪造的ICMP重定向消息&#xff0c;诱使目标主机更新其路由表&#xff0c;以便将数据包发送到攻击者控制的路由器或其他不可信任的设备上。该攻击利用了ICMP协议…

springboot配置集成RedisTemplate和Redisson,使用分布式锁案例

文章要点 自定义配置属性类集成配置RedisTemplate集成配置分布式锁Redisson使用分布式锁简单实现超卖方案 1. 项目结构 2. 集成RedisTemplate和Redisson 添加依赖 依赖的版本与继承的spring-boot-starter-parent工程相对应&#xff0c;可写可不写 <!--spring data redis…

Spring boot 集成mybatis-plus

Spring boot 集成mybatis-plus 背景 Spring boot集成mybatis后&#xff0c;我们可以使用mybatis来操作数据。然后&#xff0c;我们还是需要写许多重复的代码和sql语句&#xff0c;比如增删改查。这时候&#xff0c;我们就可以使用 mybatis-plus了&#xff0c;它可以极大解放我…

沐风老师3DMAX顶点切线控制插件VertexTangants安装使用方法

3DMAX顶点切线控制插件VertexTangants安装使用方法 3DMAX顶点切线控制插件VertexTangants&#xff0c;用于轻松控制图形顶点切线的工具。 【主要功能】 -脚本具有获取选定顶点的自动检测功能&#xff0c;您可以随时使用“获取按钮”获取选定顶点。 -有一个用于激活撤消的ON按…

项目资源管理

目录 1.概述 2.六个过程 2.1. 规划资源管理 2.2. 估算活动资源 2.3. 获取资源 2.4. 建设团队 2.5. 管理团队 2.6. 控制资源 3.应用场景 3.1.十个应用场景 3.2.软件开发项目 3.2.1. 资源规划 3.2.2. 资源分配 3.2.3. 资源获取 3.2.4. 资源优化 3.2.5. 资源监控与…

如何在外网http访问内网邮件server?

不少公司选择用winmail搭建部署内部邮箱服务器&#xff0c;对于邮件管理员&#xff0c;不但需要在局域网内&#xff0c;常常需要在外网也能访问到邮箱服务管理。winmail本身系统功能可以开启http访问管理&#xff0c;但当需要在外网http访问内网邮箱服务时&#xff0c;需要用到…

vue3通过Vite实现工程化

1. vue3简介 Vue 是一款用于构建用户界面的 JavaScript 框架。它基于标准 HTML、CSS 和 JavaScript 构建&#xff0c;并提供了一套声明式的、组件化的编程模型&#xff0c;帮助你高效地开发用户界面。无论是简单还是复杂的界面&#xff0c;Vue 都可以胜任。官网为:Vue.js - 渐进…

秋招突击——算法打卡——6/3——复习{最低通行费、(状态压缩DP)小国王}——新做:{罗马数字转整数、最长公共前缀}

文章目录 复习背包模型——最低通行费题目内容实现代码 &#xff08;状态压缩DP&#xff09;小国王检查状态本身是否存在两个连续的1计算所有的合法状态已经所有合法状态之间的转移动态规划过程 新作罗马数字转整数个人实现实现代码 参考做法实现代码 最长公共前缀个人实现参考…

Docker无法stop或者rm指定容器

Docker无法stop或者rm指定容器 今日准备重启一下docker 容器部署的 Nginx 时&#xff0c;使用的命令是 docker exec -it ir-nginx nginx -s reload 结果发现无法重启报错 然后想着关闭再启动&#xff0c;结果发现 docker restart 、docker stop 、docker kill 、docker exec 都…

【科学文献计量】使用Endnote软件打开中国知网导出的文献期刊解析不正确问题解决

使用Endnote软件打开中国知网导出的文献期刊解析不正确问题解决 问题解决问题 新建一个Endnote的材料库,然后把下载好的中国知网文献数据(知网数据导出的是Endnote格式样式)导入进来。找到文件所在路径,导入的类型选择是“Endnote import”,然后点击确定,界面结果如下 …

汇编:数据定义数据填充

数组的定义 在32位汇编语言中&#xff0c;定义数组时&#xff0c;通常使用定义数据指令&#xff08;如 DB, DW, DD,DQ &#xff09;和标签来指定数组的名称和内容。DB定义字节数组&#xff08;每个元素占1字节&#xff09;、DW定义字数组&#xff08;每个元素占2字节&#xff…

CAD 文件(DXF / DWG)转换为(DXF / PDF / PNG / SVG)

方法一Github 这个是ezdxf出品的&#xff0c;可以使用命令行的方式进行转换 ezdxf draw -o file.<png|svg|pdf> <file.dxf>也可以自己改动代码 examples/addons/drawing/pdf_export.py 但是直接运行会有误&#xff0c;以下是我改动后的代码&#xff1a; from ez…

#13前端后花园周刊-10个现代 Node.js 运行时新特性、Nextjs15、Astro4.9、CSS压缩

⚡️行业动态 JavaScript 的创建者 Brendan Eich 在 Twitter/X 上出现&#xff0c;反驳了 JS 是“最邋遢的”的说法&#xff0c;称其只有 50% 。 &#x1f4c6;发布 Next.js 15 RC 流行的 React 元框架已经准备好迎接一个主要的新版本&#xff0c;它有一个 RC&#xff0c;让…

VS2015 +Qt 新建单元测试工程报错error LNK2019,error LNK2001: 无法解析的外部符号 WinMain

项目场景&#xff1a; 使用Qt5.9.9和vs2015进行单元测试工程的创建 问题描述 创建完成后&#xff0c;编译项目&#xff0c;报错&#xff1a; error LNK2019&#xff0c;error LNK2001: 无法解析的外部符号 WinMain 原因分析&#xff1a; 原因是笔者创建工程的时候&#xf…

python如何base64编码与解码操作???

前言 之前的文章有提到Base64编码的实现原理&#xff0c;你一定非常想尝试一下&#xff0c;对吧&#xff1f;对&#xff0c;你非常想尝试一下&#xff08;不接受反驳&#xff0c;你想你想你很想&#xff09;。既然你这么想尝试&#xff0c;那今天来看一下在python中如何使用Ba…

贝锐蒲公英异地组网:降低建筑工地远程视频监控成本、简化运维

中联建设集团股份有限公司是一家建筑行业的施工单位&#xff0c;专注于建筑施工&#xff0c;业务涉及市政公用工程施工总承包、水利水电工程施工总承包、公路工程施工总承包、城市园林绿化专业承包等&#xff0c;在全国各地开展有多个建筑项目&#xff0c;并且项目时间周期可能…

Camx架构-Camera kernel Driver debugging

目录 V4L2 framework camera drivers CRM 功能性 CRM log analysis 使能CRM log: camera启动期间列举子设备: userspace 连接或者取消已获得的device handles(UMD 等效于CSLLink/CSLUnlink) userspace open request (UMD等效于CSLOpenRequest) 在SOF期间,reque…