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.创建通道Channel
    Channel 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.创建通道Channel
    Channel channel = connection.createChannel();
    // 3.创建队列
    String queueName = "simple.queue";
    channel.queueDeclare(queueName, false, false, false, null);
    // 4.订阅消息
    channel.basicConsume(queueName, true, new DefaultConsumer(channel){
        @Override
        public 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学习笔记

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

I.MX RT1170之MIPI DSI初始化和显示流程详解

MIPI DSI&#xff08;Mobile Industry Processor Interface Display Serial Interface&#xff09;是一种广泛应用于移动设备显示屏的接口标准。由MIPI联盟制定&#xff0c;DSI接口旨在提供高效、低功耗的显示屏数据传输解决方案。 本节来就通过学习I.MX RT1170单片机中的MIPI…

Vue3——实现word,pdf上传之后,预览功能(实测有效)

vue-office/pdf - npm支持多种文件(**docx、excel、pdf**)预览的vue组件库&#xff0c;支持vue2/3。也支持非Vue框架的预览。. Latest version: 2.0.2, last published: a month ago. Start using vue-office/pdf in your project by running npm i vue-office/pdf. There are …

英伟达开源新利器NV-Embed向量模型,基于双向注意力的LLM嵌入模型,MTEB 56项任务排名第一

前言 文本嵌入模型能够将文本信息转化为稠密的向量表示&#xff0c;并在信息检索、语义相似度计算、文本分类等众多自然语言处理任务中发挥着关键作用。近年来&#xff0c;基于解码器的大型语言模型 (LLM) 开始在通用文本嵌入任务中超越传统的 BERT 或 T5 嵌入模型&#xff0c…

Redis整合SpringBoot微服务基础操作

前言 首先我们先知道类似于JDBC的连接中间件在redis之间使用的是啥 首先是Jedis,这是最初代的连接redis客户端 操作也是非常的简单 Jedis 首先我们先介绍这个 我们只需要引入对应的pom文件依赖 <!--SpringBoot通用依赖模块--><dependency><groupId>org.spri…

uniapp使用uQRCode页面不显示也不报错

我使用的版本是&#xff1a;4.0.6 引入到项目中后根据官方的配置教程进行配置&#xff1a; 但是页面上就是不显示&#xff0c;也不报错&#xff0c;看官网发现步骤也没问题 解决方法&#xff1a; 这句话代表的是uQrcode会被自动引用注册&#xff0c;但是你引过组件库或者别的…

51单片机课设

1.51最小系统板原理图介绍 复位电路&#xff1a;&#xff08;简单的RC电路&#xff09; 在电路图中&#xff0c;电容的的大小是10uF&#xff0c;电阻的大小是10k。 当接通VCC后&#xff1a; 电容还没开始充电&#xff0c;电容电压为0&#xff0c;R7的电压为5V,然后电容开始充电…

盲盒小程序库存管理的关键策略

随着盲盒经济的兴起&#xff0c;越来越多的商家开始投入盲盒小程序的开发与运营。然而&#xff0c;在享受市场红利的同时&#xff0c;库存管理的问题也随之而来。合理的库存管理不仅能够满足用户需求&#xff0c;还能有效优化库存周转率&#xff0c;提升商家的盈利能力。本文将…

操作系统入门系列-MIT6.828(操作系统工程)学习笔记(四)---- C语言与计算机架构(Programming xv6 in C)

系列文章目录 操作系统入门系列-MIT6.S081&#xff08;操作系统&#xff09;学习笔记&#xff08;一&#xff09;---- 操作系统介绍与接口示例 操作系统入门系列-MIT6.828&#xff08;操作系统工程&#xff09;学习笔记&#xff08;二&#xff09;----课程实验环境搭建&#x…

【图像识别系统】表情识别Python+人工智能深度学习+TensorFlow+卷积算法网络模型+图像识别

表情识别系统&#xff0c;本系统使用Python作为主要编程语言&#xff0c;通过TensorFlow搭建ResNet50卷积神经算法网络模型&#xff0c;通过对7种表情图片数据集&#xff08;‘Neutral’, ‘Anger’, ‘Disgust’, ‘Fear’, ‘Happy’, ‘Sad’, ‘Surprise’&#xff09;进行…

安装存储器的段描述符并加载GDTR

代码清单 ;代码清单12-1;文件名&#xff1a;c12_mbr.asm;文件说明&#xff1a;硬盘主引导扇区代码;创建日期&#xff1a;2011-5-16 19:54&#xff1b;修改于2022-02-16 11:15;设置堆栈段和栈指针mov ax, csmov ss, axmov sp, 0x7c00;计算GDT所在的逻辑段地址12 mov ax, [c…

视图的相关操作

4.1.1 创建视图 语法格式&#xff1a;create [ or replace ] view view_name [ ( column_list ) ] as select_statement [ with [ cascade | local ] check option ] 说明&#xff1a; &#xff0…

Redis的SDS数据结构解决C语言字符串缺陷

redis设计了SDS这一数据结构来表示字符串而不是使用c语言的字符串&#xff1a;字符数组 那么redis为什么要大费周章自己设计字符串呢&#xff1f; 答案是C语言字符串有缺陷 1.获取字符串长度&#xff0c;需要遍历字符数组&#xff0c;时间复杂度是O&#xff08;N&#xff09…

167.二叉树:另一棵树的字树(力扣)

代码解决 /*** Definition for a binary tree node.* struct TreeNode {* int val;* TreeNode *left;* TreeNode *right;* TreeNode() : val(0), left(nullptr), right(nullptr) {}* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}* Tre…

PostgreSQL 16 小课推广

PostgreSQL 16 小课推广 1. PostgreSQL 16 基础知识 PostgreSQL 16 的特点与优势安装与配置PostgreSQL 16数据库和表的基本概念与操作数据类型与约束SQL 语言基础 2. 数据查询与操作 SELECT 语句的使用聚合函数与分组查询子查询与连接查询数据插入、更新与删除视图与索引的…

二维码生成

摘要 QRCoder 是一个功能强大的 C# 库&#xff0c;用于生成 QR 码。QR 码是一种二维码&#xff0c;可以存储大量的信息&#xff0c;并且具有良好的识别率和存储容量。使用 QRCoder&#xff0c;用户可以方便地生成各种类型的 QR 码&#xff0c;包括 URL、文本、电话号码、电子邮…

<网络安全VIP>第二篇《工业控制软件》

1 PLC PLC,(Programmable Logic Controller),可编程逻辑控制器(PLC)是种专门为在工业环境下应用而设计的数字运算操作电子系统。 2 DCS 四、DCS的发展趋势 一、DCS的基本定义 DCS是分布式控制系统(Distributed Control System)的英文缩写,在国内自控行业又称之为集…

运放IC:HC358:1MHz,轨到轨I/O,低功耗运算放大ic,供应:传感器压力传感放大器移动通讯设备音频输出便携应用烟雾监测电池驱动的设备

运放IC&#xff1a; HC358&#xff1a;1MHz&#xff0c;轨到轨I/O&#xff0c;低功耗运算放大ic 概述&#xff1a;HC358是一款轨到轨输入输出&#xff0c;电压反馈运算放大 器。输入共模范围和输出摆幅较大&#xff0c;最低工作电源电压仅 为2.1V,最高电压可达5.5V。工作环…

冥想第一千一百七十八天

1.周末&#xff0c;早上先骑着电车到绿谷公园拿了姐给的精油&#xff0c;40分钟到家。 2.早上带着媳妇吃了饭&#xff0c;等丈母娘和小侄子。一起去荥泽水乡特别的推荐。感受特别好玩。 3.晚上带着丈母娘和小侄子吃了饭&#xff0c;给送到中原福塔。回来都都12点了。 4.累的&am…

【Nacos】docker-compose启动nacos v2.2.3,启动时修改默认密码不使用naocs

1. 背景 出于安全考虑&#xff0c;我司DevOps平台自动部署的容器化nacos密码不能是弱密码或默认值 但是nacos-v2.2.3官方镜像启动后会初始化nacos用户密码为nacos&#xff0c;修改启动时的变量并没有生效。 2. 部署验证 2.1 yml文件如下 注意将derby库的初始化文件挂载出来…

群体优化算法---蜂群优化算法应用于数据挖掘

介绍 蜂群优化算法&#xff08;Bee Algorithm, BA&#xff09;及其变种主要模拟蜜蜂的觅食行为&#xff0c;以解决复杂的优化问题。这类算法通过蜜蜂之间的信息交流和协作来探索解空间&#xff0c;寻找全局最优解。主要应用于参数优化&#xff0c;结构优化&#xff0c;机器学习…