消息队列 - RabbitMQ

消息队列 - RabbitMQ

    • 1. 初识 MQ
      • 1.1 同步调用
      • 1.2 异步调用
      • 1.3.技术选型
    • 2. RabbitMQ
      • 2.1 安装
      • 2.2 收发信息
        • 2.2.1 交换机(Exchange)
        • 2.2.2 队列
        • 2.2.3 绑定关系
        • 2.2.4 发送消息
      • 2.3 数据隔离


相关文章:
SpringAMQP 快速入门
RabbitMQ 如何保证消息可靠性


1. 初识 MQ

微服务一旦拆分,必然涉及到服务之间的相互调用,之前讲到的基于 OpenFeign 的调用。这种调用中,调用者发起请求后需要等待服务提供者执行业务返回结果后,才能继续执行后面的业务。也就是说调用者在调用过程中处于阻塞状态,因此我们称这种调用方式为同步调用,也可以叫同步通讯。但在很多场景下,我们可能需要采用异步通讯的方式,为什么呢?

两种方式的区别:

  • 同步通讯:就如同打视频电话,双方的交互都是实时的。因此同一时刻你只能跟一个人打视频电话。
  • 异步通讯:就如同发微信聊天,双方的交互不是实时的,你不需要立刻给对方回应。因此你可以多线操作,同时跟多人聊天。

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

所以,如果我们的业务需要实时得到服务提供方的响应,则应该选择同步通讯(同步调用)。而如果我们追求更高的效率,并且不需要实时响应,则应该选择异步通讯(异步调用)。

1.1 同步调用

我们以注册成功后邮件通知为例

image-20231207225257184

同步调用的业务流程是:

  • 发送注册请求
  • 注册成功将信息存入数据库
  • 发送邮件通知
  • 返回成功信息

这样的业务流程会存在下面三个问题

一、性能低

由于同步调用,调用者需要等待服务提供者执行完返回结果后,才能继续向下执行,也就是说每次远程调用,调用者都是阻塞等待状态。最终整个业务的响应时长就是每次远程调用的执行时长之和:100+100+300+50 = 550ms

二、扩展性差

比如需要添加短信通知,需要在代码中添加短信服务的远程调用代码。

三、级联失效

在这个案例中,注册成功了,但是邮件通知服务出现了问题抛出了错误会让存入数据库的信息回滚导致整个注册业务失败。

需要解决这些问题就需要用异步调用的方式来代替同步调用

1.2 异步调用

异步调用方式其实就是基于消息通知的方式,一般包含三个角色:

  • 消息发送者:投递消息的人,就是原来的调用方
  • 消息Broker:管理、暂存、转发消息,你可以把它理解成微信服务器
  • 消息接收者:接收和处理消息的人,就是原来的服务提供方

image-20231207230036497

在异步调用中,发送者不再直接同步调用接收者的业务接口,而是发送一条消息投递给消息Broker。然后接收者根据自己的需求从消息Broker那里订阅消息。每当发送方发送消息后,接受者都能获取消息并处理。
这样,发送消息的人和接收消息的人就完全解耦了。

还是以注册通知为例:

image-20231207230635303

将远程调用逻辑删除,改为发送一条消息到Broker。而相关的微服务都可以订阅消息通知,一旦消息到达Broker,则会分发给每一个订阅了的微服务,处理各自的业务。

后续需要添加短信通知也只需要添加一个短信服务订阅消息即可。

而且注册服务的耗时也和其他服务无关。

综上,异步调用的优势包括:

  • 耦合度更低
  • 性能更好
  • 业务拓展性强
  • 故障隔离,避免级联失败

当然,异步通信也并非完美无缺,它存在下列缺点:

  • 完全依赖于Broker的可靠性、安全性和性能
  • 架构复杂,后期维护和调试麻烦

1.3.技术选型

消息Broker,目前常见的实现方案就是消息队列(MessageQueue),简称为MQ.
目比较常见的MQ实现:

  • ActiveMQ
  • RabbitMQ
  • RocketMQ
  • Kafka

几种常见MQ的对比:

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

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

2. RabbitMQ

RabbitMQ 是一个开源的消息中间件(Message Broker),用于在分布式系统中传递消息。它实现了高级消息队列协议(AMQP),这是一种网络协议,用于在应用程序之间传递消息。

以下是 RabbitMQ 的一些主要特性和概念:

  1. 消息队列: RabbitMQ 提供了一个消息队列,允许不同的应用程序通过消息进行通信。发送方将消息放入队列,而接收方则从队列中获取消息。
  2. 发布/订阅模型: RabbitMQ 支持发布/订阅模型,其中一个应用程序(发布者)发布消息,而多个应用程序(订阅者)可以订阅并接收这些消息。
  3. 可靠性: RabbitMQ 提供了持久性,确保即使在代理重新启动后,队列和消息也不会丢失。
  4. 灵活的路由: RabbitMQ 具有灵活的路由机制,可以根据不同的条件将消息路由到不同的队列。
  5. 多协议支持: RabbitMQ 支持多种消息传递协议,包括 AMQP、STOMP、MQTT 等。
  6. 插件系统: RabbitMQ 具有丰富的插件系统,可以通过插件扩展其功能,如集群、身份验证、可视化工具等。
  7. 可视化管理界面: RabbitMQ 提供了一个易于使用的管理界面,允许用户监视和管理队列、交换机等组件。
  8. 集群支持: RabbitMQ 支持构建集群,以提高可用性和性能。
  9. 消息确认: 客户端可以向 RabbitMQ 确认已成功处理消息,确保消息不会因为消费者故障而丢失。
  10. 死信队列: RabbitMQ 支持死信队列,用于处理无法被消费的消息。

2.1 安装

这里介绍 Docker 安装 RabbitMQ 的过程。

2.1.1 拉取镜像

docker pull rabbitmq:management #  拉取带有web界面的镜像

image-20231207210107857

2.1.2 启动容器

docker run -e RABBITMQ_DEFAULT_USER=root -e RABBITMQ_DEFAULT_PASS=root --name mq --hostname q -p 15672:15672 -p 5672:5672 -d rabbitmq:management
# -e RABBITMQ_DEFAULT_USER=root 用户名
# -e RABBITMQ_DEFAULT_PASS=root 密码

端口介绍:

  • 4369/tcp: Erlang Port Mapper Daemon (EPMD)端口,用于Erlang节点之间的通信。
  • 5671/tcp: AMQP over TLS/SSL端口,用于安全的AMQP连接。
  • 5672/tcp: 默认的AMQP端口,用于客户端连接和消息传递。
  • 15671/tcp: RabbitMQ Management插件的安全AMQP端口。
  • 25672/tcp: 集群端口,用于Erlang分布式节点之间的内部通信。
  • 15672/tcp: RabbitMQ Management插件的Web管理界面端口,通过Web界面进行RabbitMQ的管理。

image-20231207231928650

2.1.3 访问管理页面

http://ip地址:15672

image-20231207232019327

RabbitMQ对应的架构如图:

image-20231208134920751

其中包含几个角色:

  • publisher:生产者,也就是发送消息的一方
  • consumer:消费者,也就是消费消息的一方
  • queue:队列,存储消息。生产者投递的消息会暂存在消息队列中,等待消费者处理
  • exchange:交换机,负责消息路由。生产者发送的消息由交换机决定投递到哪个队列。
  • virtual host:虚拟主机,起到数据隔离的作用。每个虚拟主机相互独立,有各自的exchange、queue

2.2 收发信息

2.2.1 交换机(Exchange)

打开Exchanges选项,可以看到RabbitMQ预定义了7种交换机,这7种交换机有4种类型。
image-20231207232533500

关于交换机类型的简介:

  1. Direct Exchange(直连交换机):

    直连交换机是最简单的交换机类型。

    它将消息路由到与消息中的路由键完全匹配的队列中。

    在消息生产者指定的路由键和队列的绑定键完全相同时,消息将被发送到相应的队列。

  2. Fanout Exchange(扇出交换机):

    • 扇出交换机将消息广播到与交换机绑定的所有队列,忽略路由键。
    • 适用于广播消息给多个消费者的场景,不关心消息的具体内容。
  3. Topic Exchange(主题交换机):

    • 主题交换机通过匹配路由键和模式的方式来路由消息到队列。
    • 路由键可以包含通配符 *(匹配一个单词)和 #(匹配零个或多个单词),允许更复杂的路由规则。
  4. Headers Exchange(头交换机):

    • 头交换机使用消息的头部信息而不是路由键来决定如何路由消息。
    • 在绑定队列时指定一组键值对(headers),只有当消息的头部信息与这些键值对完全匹配时,消息才会被路由到队列。

关于预定义的7种交换机简介:

  1. AMQP default:
    • 这是一个直连交换机,是 RabbitMQ 的默认交换机。
    • 当消息的路由键与队列的绑定键完全匹配时,消息将被发送到相应的队列。
  2. amq.direct:
    • 也是一个直连交换机。
    • 类似于 AMQP 默认交换机,将消息路由到与消息中的路由键完全匹配的队列。
  3. amq.fanout:
    • 是一个扇出交换机。
    • 将消息广播到与交换机绑定的所有队列,忽略路由键。
  4. amq.headers:
    • 是一个头交换机。
    • 使用消息的头部信息而不是路由键来决定如何路由消息。在绑定队列时指定一组键值对(headers)。
  5. amq.match:
    • 是一个主题交换机。
    • 通过匹配路由键和模式的方式来路由消息到队列。支持更复杂的路由规则。
  6. amq.rabbitmq.trace:
    • 这是一个专用于消息追踪的交换机。
    • 用于在 RabbitMQ 中追踪消息的流动,通常不用于常规消息传递。
  7. amq.topic:
    • 也是一个主题交换机。
    • 通过匹配路由键和模式的方式来路由消息到队列。类似于 amq.match,支持更复杂的路由规则。
2.2.2 队列

打开Queues选项卡,新建一个队列:

image-20231208133420881

image-20231208133500631

2.2.3 绑定关系

点击 amq.fanout 交换机

image-20231208133656411

绑定队列 queue1

image-20231208133615746

image-20231208133641084

2.2.4 发送消息

点击 amq.fanout 交换机

image-20231208133925673

发送消息

image-20231208133915372

队列成功收到消息

image-20231208133941568

image-20231208133958825

2.3 数据隔离

RabbitMQ 使用 virtual host 实现数据隔离

新建一个虚拟主机

image-20231208140406859

添加一个用户

image-20231208140459340

现在用户test还没有能访问的虚拟主机

image-20231208140549326

切换登录用户test后无法获取没有访问权限的虚拟主机的队列消息。

image-20231208135723332

点击test为用户添加虚拟主机

image-20231208140634479

image-20231208140658453

右上角 虚拟主机切换为 /test 看不到其他虚拟主机的消息队列,这就是基于virtual host 的隔离效果。

image-20231208140741872

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

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

相关文章

beyond compare文件夹比较时候文本乱码问题解决

“格式”,在下面的左侧编码重写和右侧编码覆盖选择 GB2312/UTF-8/GBK,这个可以根据自己喜好和文本自身的encode选择。

C++ 指针基础

指针的定义 #define _CRT_SECURE_NO_WARNINGS #include <stdio.h>int main() {int a 10;printf("%p\n", &a); // &a 表示取&#xff08;a&#xff09;的地址 000000842FD9FB64// 存放指针&#xff08;地址&#xff09;的变量就是指针变量&#xff0c…

Java中的链表

文章目录 前言一、链表的概念及结构二、单向不带头非循坏链表的实现2.1打印链表2.2求链表的长度2.3头插法2.4尾插法2.5任意位置插入2.6查找是否包含某个元素的节点2.7删除第一次出现这个元素的节点2.8删除包含这个元素的所以节点2.9清空链表单向链表的测试 三、双向不带头非循坏…

spring 笔记三 Spring与Web环境集成

文章目录 Spring与Web环境集成ApplicationContext应用上下文获取方式导入Spring集成web的坐标置ContextLoaderListener监听器通过工具获得应用上下文对象SpringMVC概述SpringMVC快速入门 Spring与Web环境集成 ApplicationContext应用上下文获取方式 应用上下文对象是通过new …

leetcode面试经典150题——36 旋转图像

题目&#xff1a; 旋转图像 描述&#xff1a; 给定一个 n n 的二维矩阵 matrix 表示一个图像。请你将图像顺时针旋转 90 度。 你必须在 原地 旋转图像&#xff0c;这意味着你需要直接修改输入的二维矩阵。请不要 使用另一个矩阵来旋转图像。 示例 1&#xff1a; 输入&#x…

中国经济增长:全球复苏的引擎

近年来&#xff0c;中国经济以其强劲的增长势头成为全球经济的重要引擎。中国的经济崛起不仅对自身国家发展具有重要意义&#xff0c;而且也对全球经济复苏和稳定有着积极影响。本文将从多个角度探讨中国经济增长对全球经济的影响及其作为全球复苏的引擎。 首先&#xff0c;中国…

《使用ThinkPHP6开发项目》 - ThinkPHP6使用JWT生成Token

《使用ThinkPHP6开发项目》 - 登录接口一-CSDN博客 《使用ThinkPHP6开发项目》 - 登录接口二-CSDN博客 《使用ThinkPHP6开发项目》 - 登录接口三【表单验证】-CSDN博客 登录接口成功后返回Token&#xff0c;便于其他需要验证用户登录的接口携带Token进行请求校验 这里Think…

基于ssm网络安全宣传网站设计论文

摘 要 现代经济快节奏发展以及不断完善升级的信息化技术&#xff0c;让传统数据信息的管理升级为软件存储&#xff0c;归纳&#xff0c;集中处理数据信息的管理方式。本网络安全宣传网站就是在这样的大环境下诞生&#xff0c;其可以帮助管理者在短时间内处理完毕庞大的数据信息…

SI24R03国产自主可控RISC-V架构MCU低功耗2.4GHz收发芯片SoC

目录 RISC-V架构的优势SI24R03/04特性射频收发器模块特征MCU 模块特征 其他特征 RISC-V架构的优势 相对于目前主流的英特尔X86架构及ARM等架构来说&#xff0c;RISC-V架构具有指令精简、模块化、可扩展、开源、免费等优点。RISC-V的基础指令集只有40多条&#xff0c;加上其他基…

爬虫的分类

爬虫的分类 网络爬虫按照系统结构和实现技术&#xff0c;大致可分为4类&#xff0c;即通用网络爬虫、聚焦网络爬虫、增量网络爬虫和深层次网络爬虫。 1.通用网络爬虫&#xff1a;搜索引擎的爬虫 比如用户在百度搜索引擎上检索对应关键词时&#xff0c;百度将对关键词进行分析…

比特币价格创新高:加密货币的崛起与未来

一、引言 近年来&#xff0c;比特币的价格一路上涨&#xff0c;引起了全球投资者和市场的广泛关注。作为最早一批区块链技术应用案例之一&#xff0c;比特币的成功带动了整个加密货币市场的兴起。本文将探讨比特币价格创新高的原因、加密货币的崛起以及未来发展趋势。 二、比特…

ChatGPT热门项目

1.智能GPT 项目地址&#xff1a;智能GPT&#xff1a;你只要提供OpenAI的API Key&#xff0c;那么它就可以根据你设定的目标&#xff0c;采用Google搜索、浏览网站、执行脚本等方式 主要语言&#xff1a;Python 推荐理由&#xff1a;这是由开发者Significant Gravitas推出的项目…

【C++练级之路】【Lv.4】类和对象(下)(初始化列表,友元,static成员,编译器的优化)

目录 一、再谈构造函数1.1 构造函数体赋值1.2 初始化列表1.3 explicit关键字 二、static成员2.1 概念2.2 特性 三、友元3.1 引入3.2 友元函数3.2.1 概念3.2.2 特性 3.3 友元类3.3.1 概念3.3.2 特性 四、内部类4.1 概念4.2 特性 五、匿名对象六、编译器的优化6.1 传参优化6.1.1 …

Java EE 网络之网络初识

文章目录 1. 网络发展史1.1 独立模式1.2 网络互连1.3 局域网 LAN1.4 广域网 WAN 2. 网络通信基础2.1 IP 地址2.2 端口号2.3 认识协议2.4 五元组2.5 协议分层2.5.1 什么是协议分层2.5.2 分层的作用2.5.3 OSI七层协议2.5.4 TCP/IP五层协议2.5.5 网络设备所在分层 2.6 分装和分用 …

简单的教务系统

#include <stdio.h> #include <string.h> #define N 20 int i,j,n,m,lll0,renshu6; double zcj[N]{0};struct stu{ char num[10]; //学号char name[10]; //姓名char sex; //姓别double score[3]; //3 门课的成绩double sum; //3 门课的总分double aver; //3 门课的…

【深度学习目标检测】五、基于深度学习的安全帽识别(python,目标检测)

深度学习目标检测方法则是利用深度神经网络模型进行目标检测&#xff0c;主要有以下几种&#xff1a; R-CNN系列&#xff1a;包括R-CNN、Fast R-CNN、Faster R-CNN等&#xff0c;通过候选区域法生成候选目标区域&#xff0c;然后使用卷积神经网络提取特征&#xff0c;并通过分类…

超聚变服务器(原华为服务器)网站模拟器

一、超聚变服务器&#xff08;原华为服务器&#xff09;网站模拟器&#xff1a; 原来了解服务器可以从他的网站上进行了解&#xff0c;模拟器做的很好了。 https://support.xfusion.com/server-simulators/ 有很多的模拟器&#xff0c;今天主要看下BMC的设置 有很多的在线工具…

vue中element-ui日期选择组件el-date-picker 清空所选时间,会将model绑定的值设置为null 问题 及 限制起止日期范围

一、问题 在Vue中使用Element UI的日期选择组件 <el-date-picker>&#xff0c;当你清空所选时间时&#xff0c;组件会将绑定的 v-model 值设置为 null。这是日期选择器的预设行为&#xff0c;它将清空所选日期后将其视为 null。但有时后端不允许日期传空。 因此&#xff…

生产实践:基于K8S的私有化部署解决方案

随着国内数字化转型的加速和国产化进程推动&#xff0c;软件系统的私有化部署已经成为非常热门的话题&#xff0c;因为私有化部署赋予了企业更大的灵活和控制权&#xff0c;使其可以根据自身需求和安全要求定制和管理软件系统。下面分享下我们的基于k8S私有化部署经验。 私有化…

AR眼镜光学方案_AR眼镜整机硬件定制

增强现实(Augmented Reality&#xff0c;AR)技术通过将计算机生成的虚拟物体或其他信息叠加到真实世界中&#xff0c;实现对现实的增强。AR眼镜作为实现AR技术的重要设备&#xff0c;具备虚实结合、实时交互的特点。为了实现透视效果&#xff0c;AR眼镜需要同时显示真实的外部世…