RabbitMQ简单介绍

什么是消息队列

消息队列是一种在应用程序之间传递消息的通信模式。它提供了一种异步的、可靠的方式来处理分布式系统中的消息传递。在消息队列中,消息发送者(Producer)将消息发送到队列(Queue)中,而消息接收者(Consumer)则从队列中获取消息进行处理。消息队列作为中间件,解耦了消息的发送者和接收者,使它们可以独立地进行操作。

消息队列通常应用场景

  1. 异步任务处理:将耗时的任务或业务逻辑作为消息发送到队列中,在后台异步处理,提高系统的响应速度和并发处理能力。
  2. 解耦系统组件:不同的系统组件之间通过消息队列进行通信,实现解耦,使得系统的各个组件可以独立地进行扩展、修改和替换,提高系统的灵活性。
  3. 系统解耦和削峰填谷:将请求发送到消息队列中,由另一个系统或服务来处理请求,减轻系统的负载压力,实现削峰填谷。
  4. 日志收集和处理:将系统产生的日志消息发送到消息队列中,再由消费者进行处理、分析和存储,方便日志的集中管理和实时监控。
  5. 事件驱动架构:通过消息队列来实现系统的事件驱动架构,不同的系统组件可以通过消息的发布和订阅机制进行解耦和通信。
  6. 消息广播和通知:将消息广播到多个订阅者,实现实时通知、广播和推送功能,例如实时聊天系统、新闻订阅等。
  7. 分布式事务:通过消息队列来实现分布式事务的最终一致性,确保不同系统之间的数据一致性。
  8. 应用解耦和系统集成:将不同的应用程序之间通过消息队列进行集成,实现数据的传递和共享。

RabbitMQ简介

RabbitMQ是由erlang语言开发,基于AMQP(Advanced Message Queue 高级消息队列协议)协议实现的消息队列,它是一种应用程序之间的通信方法。常用于在分布式系统中存储、转发消息,从而实现系统之间的解耦,支持多种客户端,包括Python、Ruby、.NET、Java等。RabbitMQ官方地址:http://www.rabbitmq.com

RabbitMQ工作原理

RabbitMQ结构图

img

组成部分说明

  1. Producer(消息生产者):Producer是消息的发送者,它将消息发送到RabbitMQ中的交换机(Exchange)。Producer可以将消息发送到特定的交换机,并指定一个路由键(Routing Key)来标识消息的路由规则。
  2. Exchange(交换机):Exchange是消息的接收和分发中心。Producer将消息发送到交换机,交换机根据指定的路由键将消息路由到一个或多个绑定的队列中。
  • Direct Exchange(直连交换机):根据消息的路由键与绑定的队列进行精确匹配。
  • Topic Exchange(主题交换机):根据消息的路由键与绑定的队列进行模式匹配,支持通配符的路由键。
  • Fanout Exchange(扇形交换机):将消息广播给所有绑定的队列,忽略路由键。
  1. Queue(队列):Queue是消息的存储地点。它是RabbitMQ中的核心组件,用于存储待处理的消息。消息发送到队列后,等待消费者(Consumer)从队列中获取并处理消息。
  2. Binding(绑定):绑定是交换机和队列之间的关联关系。它定义了交换机如何将消息路由到特定的队列。绑定包括交换机名称、队列名称和可选的路由键。
  3. Consumer(消息消费者):Consumer是消息的接收者,它从队列中获取消息并进行处理。当有消息到达队列时,RabbitMQ将消息发送给一个或多个消费者进行处理。
  4. Connect(连接):Connect是Producer和Consumer与RabbitMQ之间建立的网络连接。每个应用程序都可以建立一个或多个Connect,用于与RabbitMQ进行通信。
  5. Channel(通道):Channel是建立在Connection上的虚拟连接。Producer和Consumer使用Channel来进行消息的发送和接收。通过使用多个Channel,可以实现并行处理多个消息的能力。
  6. Virtual Host(虚拟主机):Virtual Host是逻辑上的概念,用于对RabbitMQ进行逻辑分区。每个Virtual Host拥有自己的独立的交换机、队列、绑定等资源,实现了逻辑上的隔离。
  7. Broker:消息队列服务进程,此进程包括两个部分:Exchange和Queue

生产者发送消息流程

  1. 建立连接:生产者首先与 RabbitMQ 建立连接。连接包含 RabbitMQ 服务器的地址、端口和认证凭据等信息。

  2. 创建通道:在建立连接后,生产者必须创建一个通道(Channel)。通道是建立在连接上的虚拟连接,用于进行消息的发送和接收。通过通道,可以实现并发处理多个消息。

  3. 声明交换机:生产者需要声明要发送消息的交换机(Exchange)。交换机负责接收消息,并根据指定的路由键将消息路由到一个或多个绑定的队列。

  4. 声明队列(可选):如果生产者发送的消息需要直接发送到特定的队列,而不经过交换机的路由规则,那么生产者需要声明要发送消息的队列。如果队列不存在,RabbitMQ将自动创建该队列。

  5. 发布消息:生产者使用通道的 basicPublish 方法来发布消息。在发布消息时,需要指定以下参数:

    • 交换机名称:消息将被发送到的交换机。
    • 路由键(Routing Key):用于将消息路由到特定的队列。
    • 消息内容:要发送的实际消息数据。
  6. 关闭通道和连接:在完成消息发送后,生产者应该关闭通道和连接,释放资源。

消费者接收消息流程

  1. 建立连接:消费者首先与 RabbitMQ 建立连接。连接包含 RabbitMQ 服务器的地址、端口和认证凭据等信息。

  2. 创建通道:在建立连接后,消费者必须创建一个通道(Channel)。通道是建立在连接上的虚拟连接,用于进行消息的发送和接收。通过通道,可以实现并发处理多个消息。

  3. 声明队列:消费者需要声明要接收消息的队列。如果队列不存在,RabbitMQ将自动创建该队列。

  4. 绑定队列和交换机:消费者将队列绑定到特定的交换机上,以便从交换机接收消息。绑定需要指定交换机名称、队列名称和可选的路由键。

  5. 消息消费:消费者使用通道的 basicConsume 方法来开始消费消息。在消费消息时,需要指定以下参数:

    • 队列名称:要消费的队列。
    • 消费回调函数:当消费者接收到消息时,会调用该回调函数进行处理。
  6. 消费者通过订阅队列并注册回调函数,当有消息到达队列时,RabbitMQ会将消息发送给消费者进行处理。

  7. 处理消息:消费者在收到消息后,通过回调函数对消息进行处理。处理可以包括解析消息内容、执行特定的业务逻辑等操作。

  8. 消息确认(可选):消费者可以选择确认消息的接收,以确保消息已经成功处理。确认可以通过调用通道的 basicAck 方法来实现。

  9. 关闭通道和连接:在完成消息处理后,消费者应该关闭通道和连接,释放资源。

六种消息模型

基本消息模型

基本消息模型示意图:

img

  • P:生产者,就是发送消息的应用程序
  • C:消费者:就是接收消息的应用程序,它会一直等待消息的到来
  • queue:消息队列,图中红色长条部分,可以缓存消息;生产者向队列中投递消息,消费者从队列中获取出消息。

work消息模型

工作队列或者竞争消费者模示意图:

img

work queues与基本消息模型对比,多了一个消费者,两个消费者共同消费同一个队列中的消息,但是一个消息只能被一个消费者获取,两者是竞争关系

P:生产者:发送消息的应用程序

C1:消费者1:接收消息并且完成相应的任务,假设完成速度较慢(耗时10s)

C2:消费者2:接收消息并且完成相应的任务,假设完成速度较快(耗时2s)

这时生产者发送了5条消息,C1消费了1条,C2消费了4条,体现了能者多劳的关系,现实中对应机器设备处理任务的速度快慢。

Publish/subscribe模型

交换机类型:Fanout,也称为广播

Publish/subscribe模型示意图 :

img

P:生产者:发送消息的应用程序

X:交换机:与队列进行绑定

Queue:消息队列,图中红色长条部分,可以缓存消息;生产者向队列中投递消息,消费者从队列中获取出消息

C1:消费者1:接收消息并且完成相应的任务

C2:消费者2:接收消息并且完成相应的任务

与前面两种模式不同

生产者与交换机(Exchange)进行绑定,不再与队列(Queue)直接绑定

生产者发送消息到交换机(Exchange),不再直接发送到队列(Queue)

这是生产者发送一条消息,消费者1、消费者2都能接收到消息,就跟广播一样,播放音乐大家都能听到

Routing 路由模型

交换机类型:direct

Routing模型示意图:

img

P:生产者,向Exchange发送消息,发送消息时,会指定一个routing key。

X:Exchange(交换机),接收生产者的消息,然后把消息递交给 与routing key完全匹配的队列

C1:消费者1,接收到所在队列指定了routing key 为 error 的消息

C2:消费者2,接收到所在队列指定了routing key 为 info、error、warning 的消息

这时生产者发送消息,交换机会根据routing key发送到特定的队列中,不同的routing key可以绑定到相同的队列中。

Topics 通配符模型

交换机类型:topics

Topics模型示意图:

img

P:生产者,向Exchange发送消息,发送消息时,会指定一个routing key。

X:Exchange(交换机),Exchange类型为Topic Exchange,接收生产者的消息,然后把消息递交给与通配符routing key匹配(跟正则匹配差不多)的队列

C1:消费者1,接收到Q1队列的消息

C2:消费者2,接收到Q2队列的消息

这时生产者将消息发给broker,由交换机根据通配符routingkey来转发消息到指定的队列,每个消费者监听自己的

队列。

Routingkey一般都是有一个或者多个单词组成的,多个单词之间是以“.”作为分割,例如:inform.order

通配符规则:

#:匹配一个或多个词

*:匹配1个词

举例:

inform.#:能够匹配inform.user.name 或者 audit.order

audit.*:只能匹配audit.order

保证消息的稳定性

消息持久化

RabbitMQ的消息默认存在内存中的,一旦服务器意外挂掉,消息就会丢失

消息持久化需做到三点

  • Exchange设置持久化
  • Queue设置持久化
  • Message持久化发送:发送消息设置发送模式deliveryMode=2,代表持久化消息

ACK确认机制

多个消费者同时收取消息,收取消息到一半,突然某个消费者挂掉,要保证此条消息不丢失,就需要acknowledgement机制,就是消费者消费完要通知服务端,服务端才将数据删除

这样就解决了,及时一个消费者出了问题,没有同步消息给服务端,还有其他的消费端去消费,保证了消息不丢的case。

设置集群镜像模式

我们先来介绍下RabbitMQ三种部署模式:

1)单节点模式:最简单的情况,非集群模式,节点挂了,消息就不能用了。业务可能瘫痪,只能等待。

2)普通模式:默认的集群模式,某个节点挂了,该节点上的消息不能用,有影响的业务瘫痪,只能等待节点恢复重启可用(必须持久化消息情况下)。

3)镜像模式:把需要的队列做成镜像队列,存在于多个节点,属于RabbitMQ的HA方案

为什么设置镜像模式集群,因为队列的内容仅仅存在某一个节点上面,不会存在所有节点上面,所有节点仅仅存放消息结构和元数据。下面自己画了一张图介绍普通集群丢失消息情况

消息补偿机制

持久化的消息,保存到硬盘过程中,当前队列节点挂了,存储节点硬盘又坏了,消息丢了,怎么办?

产线网络环境太复杂,所以不知数太多,消息补偿机制需要建立在消息要写入DB日志,发送日志,接受日志,两者的状态必须记录。

然后根据DB日志记录check 消息发送消费是否成功,不成功,进行消息补偿措施,重新发送消息处理。

如何实现延迟队列

RabbitMQ本身没有延迟队列,需要靠TTL和DLX模拟出延迟的效果

TTL(Time To Live)

RabbitMQ可以针对Queue和Message设置 x-message-tt,来控制消息的生存时间,如果超时,则消息变为dead letter

RabbitMQ针对队列中的消息过期时间有两种方法可以设置。

A: 通过队列属性设置,队列中所有消息都有相同的过期时间。

B: 对消息进行单独设置,每条消息TTL可以不同。

如果同时使用,则消息的过期时间以两者之间TTL较小的那个数值为准。消息在队列的生存时间一旦超过设置的TTL值,就成为dead letter

DLX (Dead-Letter-Exchange)

RabbitMQ的Queue可以配置x-dead-letter-exchange 和x-dead-letter-routing-key(可选)两个参数,如果队列内出现了dead letter,则按照这两个参数重新路由。

x-dead-letter-exchange:出现dead letter之后将dead letter重新发送到指定exchange

x-dead-letter-routing-key:指定routing-key发送

队列出现dead letter的情况有:

  • 消息或者队列的TTL过期
  • 队列达到最大长度
  • 消息被消费端拒绝(basic.reject or basic.nack)并且requeue=false

利用DLX,当消息在一个队列中变成死信后,它能被重新publish到另一个Exchange。这时候消息就可以重新被消费。

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

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

相关文章

R语言 | 上下双向柱状图

1. 效果图 2. 代码 # 生成测试数据 difdata.frame(labelspaste0("pathway", 1:3),upc(30,15,1),downc(10,20,40) ) rownames(dif)dif$labels dif#变形 difreshape2::melt(dif) dif# 绘图 ggplot(dif, aes(xlabels, yifelse(variable"up", value, -value), …

ubuntu 中安装docker

1 资源地址 进入ubuntu官网下载Ubuntu23.04的版本的镜像 2 安装ubuntu 这里选择再Vmware上安装Ubuntu23.04.6 创建一个虚拟机,下一步下一步 注意虚拟机配置网络桥接,CD/DVD选择本地的镜像地址 开启此虚拟机,下一步下一步等待镜像安装。 3…

边缘计算迎来“量子飞跃”!支持抗量子密码,AMD推出FPGA新系列

3月6日,AMD宣布推出AMD Spartan™ UltraScale™ FPGA系列,这是AMD成本优化FPGA和自适应SoC广泛产品组合的最新成员。 距离1月22日,AMD推出业界首款符合VESA DisplayPort 2.1标准的FPGA和自适应SoC实现,也才过了一个多月的时间。 S…

【pytest、playwright】allure报告生成视频和图片

目录 1、修改插件pytest_playwright 2、conftest.py配置 3、修改pytest.ini文件 4、运行case 5、注意事项 1、修改插件pytest_playwright pytest_playwright.py内容如下: # Copyright (c) Microsoft Corporation. # # Licensed under the Apache License, Ver…

前端埋点全解及埋点SDK实现方式

一、什么是埋点 所谓“埋点”,是数据采集领域(尤其是用户行为数据采集领域)的术语,指的是针对特定用户行为或事件进行捕获、处理和发送的相关技术及其实施过程。比如用户某个icon点击次数、观看某个视频的时长等等。 埋点…

Day22 LeedCode:235.二叉搜索树的最近公共祖先 701.二叉搜索树的插入操作 450.删除二叉搜索树的结点

235. 二叉搜索树的最近公共祖先 给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先。 百度百科中最近公共祖先的定义为:“对于有根树 T 的两个结点 p、q,最近公共祖先表示为一个结点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大&…

openGauss增量备份恢复

openGauss 增量备份恢复 openGauss 数据库自 2020 年 6 月 30 日发布以来,很多小伙伴都提到“openGauss 数据库是否有增量备份工具?“这么一个问题。 在 openGauss 1.0.0 版本的时候,关于这个问题的回答往往是:“Sorry…”&…

ClickHouse10-ClickHouse中Kafka表引擎

Kafka表引擎也是一种常见的表引擎,在很多大数据量的场景下,会从源通过Kafka将数据输送到ClickHouse,Kafka作为输送的方式,ClickHouse作为存储引擎与查询引擎,大数据量的数据可以得到快速的、高压缩的存储。 Kafka大家…

免费SSL证书和付费SSL证书的区别点

背景: 在了解免费SSL证书和付费SSL证书的区别之前,先带大家了解一下SSL证书的概念和作用。 SSL证书的概念: SSL证书就是基于http超文本传输协议的延伸,在http访问的基础上增加了一个文本传输加密的协议,由于http是明…

【SQL】1633. 各赛事的用户注册率(COUNT函数 表达式用法)

题目描述 leetcode题目:1633. 各赛事的用户注册率 Code select contest_id, round(count(*)/(select count(*) from Users)*100, 2) as percentage from Register group by contest_id order by percentage desc, contest_id ascCOUNT()函数 COUNT函数用法&#…

每日一题 --- 链表相交[力扣][Go]

链表相交 题目:面试题 02.07. 链表相交 给你两个单链表的头节点 headA 和 headB ,请你找出并返回两个单链表相交的起始节点。如果两个链表没有交点,返回 null 。 图示两个链表在节点 c1 开始相交**:** 题目数据 保证 整个链式结…

【每日力扣】452. 用最少数量的箭引爆气球与763. 划分字母区间

🔥 个人主页: 黑洞晓威 😀你不必等到非常厉害,才敢开始,你需要开始,才会变的非常厉害。 452. 用最少数量的箭引爆气球 有一些球形气球贴在一堵用 XY 平面表示的墙面上。墙面上的气球记录在整数数组 points &#xff0…

Chronos: 将时间序列作为一种语言进行学习

这是一篇非常有意思的论文,它将时间序列分块并作为语言模型中的一个token来进行学习,并且得到了很好的效果。 Chronos是一个对时间序列数据的概率模型进行预训练的框架,它将这些值标记为与基于transformer的模型(如T5)一起使用。模型将序列的…

阿里云ubuntu服务器搭建可视化界面

连接终端 最好初始化服务器的时候 不要以root权限创建 否则会出错 1更新软件: sudo apt-get update2安装ubuntu desktop : sudo apt-get install ubuntu-desktop3 配置ubuntu desktop并重启: sudo apt-get -f install sudo dpkg-reconfigure ubuntu-desktop sudo reboot4 su…

【MySQL】13. 索引(重点)

1. 没有索引,可能会有什么问题 索引:提高数据库的性能,索引是物美价廉的东西了。 不用加内存,不用改程序,不用调sql,只要执行正确的 create index ,查询速度就可能提高成百上千倍。 但是天下没…

VMware ESXi部署macOS Monterey

正文共:1024 字 30 图,预估阅读时间:2 分钟 最早使用黑苹果是在2015年,装在了古老的Acer商务本上(老樹發新芽,acer tm 4750g裝黑蘋果);上次安装黑苹果是在两年前(VMware…

深入理解element-plus table二次封装:从理论到实践的全面指南

前言 在许多中后台管理系统中,表格占据着半壁江山,如果使用element plus组件库,那么少不了要用到table组件,可是table组件的功能过于基础,因此,我在table组件的实现基础之上进一步封装,从而实现…

Windows直接运行python程序

Windows直接运行python程序 一、新建bat脚本二、新建vbs脚本 一、新建bat脚本 新建bat批处理脚本,写入以下内容 echo off call conda activate pytorch python app.pyecho off:在此语句后所有运行的命令都不显示命令行本身,但是本身的指令是…

微信小程序的页面交互练习——实现比较两数大小功能

前提&#xff1a;配置好页面后 一、在wxml里面搭建好框架&#xff1a; <navigation-bar title"Weixin" back"{{false}}" color"black" background"#FFF"></navigation-bar> <scroll-view class"scrollarea"…

简单了解原型模式

什么是原型模式 区别于单例模式&#xff0c;原型模式的一个类可以有多个实例化的对象。 原型模式通过拷贝来产生新的对象&#xff0c;而不是new&#xff0c;并且可以根据自己的需求修改对象的属性。 实现Cloneable接口实现拷贝 而拷贝又分为浅拷贝和深拷贝&#xff0c;两者在…