RabbitMQ 教程 | 第9章 RabbitMQ 高阶

news2024/11/13 16:01:51

👨🏻‍💻 热爱摄影的程序员
👨🏻‍🎨 喜欢编码的设计师
🧕🏻 擅长设计的剪辑师
🧑🏻‍🏫 一位高冷无情的编码爱好者
大家好,我是 DevOps 工程师
欢迎分享 / 收藏 / 赞 / 在看!

这篇 RabbitMQ 教程为学习者提供了全面的内容,从 RabbitMQ 的简介开始,涵盖了消息中间件的概念、RabbitMQ 的安装与使用,以及交换机、队列、路由键等相关概念的介绍。进一步深入,教程探讨了 AMQP 协议、客户端开发向导,以及消息的发送和消费方式。同时,学习者还可以了解消息传输保障、高级特性如死信队列、延迟队列、优先级队列、RPC 实现等。此外,教程还涵盖了 RabbitMQ 的管理、配置、运维、监控和集群管理等重要主题,帮助学习者充分掌握 RabbitMQ 的应用。整篇教程丰富内容详实,适合初学者和有经验的开发者参考学习。

全篇共 11 章,9 万余字。本文:第9章 RabbitMQ 高阶。

第9章 RabbitMQ 高阶

9.1 存储机制

学习 RabbitMQ 中队列的存储机制,了解如何管理队列中的消息。

9.1.1 队列的结构

在 RabbitMQ 中,队列是用于存储消息的数据结构,它是消息的终点和消费者的起点。队列在 RabbitMQ 服务器中以一种特定的存储结构进行存储,并支持不同的存储方式来保证消息的可靠传递。

存储结构: RabbitMQ 中的队列是一种先进先出(FIFO)的数据结构。它类似于一个缓冲区,消息通过生产者发送到队列的末尾,然后由消费者从队列的头部依次取出。因此,先进入队列的消息会被先处理,保证了消息的顺序性。

存储方式:

  1. 内存存储: 默认情况下,RabbitMQ 使用内存存储消息。这种方式对于消息的传递速度非常快,适用于高吞吐量的场景。然而,内存存储是易失性的,当 RabbitMQ 服务器重启时,内存中的消息会丢失,因此不适用于要求消息持久化的场景。
  2. 磁盘存储: 为了保证消息的持久性,在需要持久化消息的场景下,可以将队列配置为使用磁盘存储。通过将消息持久化到磁盘,即使 RabbitMQ 服务器重启,消息也不会丢失。磁盘存储在消息的可靠性方面提供了保障,但对于高吞吐量的场景可能会影响性能。
  3. 惰性队列: RabbitMQ 还提供了一种特殊类型的队列,称为"惰性队列"。惰性队列在内存中存储尽可能少的数据,并且将剩余的消息持久化到磁盘。这种存储方式既保证了消息的持久性,又降低了内存占用,适用于需要持久化的场景但又不想完全牺牲性能的情况。

选择合适的存储方式取决于应用的需求和场景。如果对消息的持久性要求很高,可以使用磁盘存储;如果需要兼顾性能和持久性,可以考虑惰性队列;如果对性能要求非常高且可以容忍消息的丢失,可以使用内存存储。在实际应用中,需要根据具体情况选择最合适的存储方式。

9.1.2 惰性队列

惰性队列(Lazy Queues)是 RabbitMQ 中一种特殊的队列类型,其特性和适用场景如下:

特性:

  1. 内存优化:惰性队列在内存中存储尽可能少的数据,将大部分消息持久化到磁盘上。这样可以显著减少内存占用,特别适用于大量消息积压的场景。
  2. 懒加载:惰性队列仅在需要时才会从磁盘中读取消息到内存中进行处理,避免了一次性将大量消息全部加载到内存的开销,提高了队列的处理性能。
  3. 持久性:惰性队列将消息持久化到磁盘,即使 RabbitMQ 服务器重启,消息也不会丢失,保证了消息的可靠性。

适用场景: 使用惰性队列的主要场景包括:

  1. 大量消息积压:当队列中积压了大量的消息,内存不足以容纳全部消息时,可以考虑使用惰性队列来减少内存占用,从而避免 RabbitMQ 服务器因内存不足而宕机。
  2. 持久性要求高:当应用对消息的持久性要求较高,不希望消息在 RabbitMQ 服务器重启时丢失时,可以选择使用惰性队列进行消息持久化。
  3. 消息延迟处理:由于惰性队列在读取磁盘上的消息时需要额外的 IO 操作,因此可能会引入一定的延迟。在对消息的处理时允许一定的延迟的场景中,可以考虑使用惰性队列。

需要注意的是,惰性队列的性能可能不如内存队列,因为它需要进行额外的 IO 操作。因此,在选择队列类型时,需要根据应用的实际需求来权衡性能和持久性。如果应用的内存资源有限,并且对消息的持久性有要求,那么惰性队列是一个很好的选择。否则,如果对性能要求非常高且可以容忍一定的消息丢失,可以考虑使用内存队列。

9.2 内存及磁盘告警

学习如何设置内存和磁盘的告警阈值,以便及时处理资源不足问题。

9.2.1 内存告警

在 RabbitMQ 中,可以设置内存告警阈值来监控节点的内存使用情况,并在达到预设阈值时触发内存告警事件。当节点的内存使用量接近或超过设定的内存告警阈值时,RabbitMQ 会发出内存告警通知。这样可以帮助管理员及时发现并处理内存资源不足的情况,以避免可能的性能问题或系统崩溃。

设置内存告警阈值: 可以通过 RabbitMQ 的配置文件或者管理插件来设置内存告警阈值。

  1. 通过配置文件设置: 打开 RabbitMQ 的配置文件(通常位于 /etc/rabbitmq/rabbitmq.conf 或 /etc/rabbitmq/rabbitmq-env.conf),添加以下配置项来设置内存告警阈值:

vm_memory_high_watermark.relative = 0.4

这里的 0.4 表示内存告警阈值相对于节点可用内存的百分比,此处设置为 40%。可以根据实际情况调整阈值。

  1. 通过管理插件设置: 如果安装了 RabbitMQ 的管理插件(rabbitmq_management),可以通过 Web 管理界面来设置内存告警阈值。在"Admin" -> "Global Parameters" -> "Memory High Watermark"处设置阈值。

处理内存告警事件: 一旦内存使用量达到设定的内存告警阈值,RabbitMQ 会发出内存告警通知。处理内存告警事件的方式可以有以下几种:

  1. 增加节点内存: 如果 RabbitMQ 节点的内存使用量经常接近或超过内存告警阈值,说明节点的内存资源可能不足,可以考虑增加节点的内存来提高系统性能。
  2. 优化消费者端: 内存告警事件可能是由于消息消费者处理速度不够快,导致消息在队列中积压而引起的。优化消费者端的处理逻辑,提高消费速度,有助于减轻内存压力。
  3. 增加节点数量: 在集群环境中,如果某个节点的内存使用量持续高于内存告警阈值,可以考虑增加节点数量,将部分负载分散到新节点上,从而降低每个节点的内存负载。
  4. 重启 RabbitMQ 节点: 在处理内存告警事件时,有时候简单的重启 RabbitMQ 节点也可以释放内存资源,缓解内存告警情况。

总之,设置合理的内存告警阈值,及时处理内存告警事件,可以帮助保障 RabbitMQ 的稳定运行和性能表现。根据具体的业务需求和资源情况,灵活调整内存告警阈值以及处理策略是非常重要的。

9.2.2 磁盘告警

了解如何设置磁盘告警阈值:

在 RabbitMQ 中,可以设置磁盘告警阈值来监控节点的磁盘使用情况,并在磁盘使用量接近或超过设定阈值时触发磁盘告警事件。这样可以帮助管理员及时发现并处理磁盘资源不足的情况,以避免可能的性能问题或数据丢失。

设置磁盘告警阈值通常通过 RabbitMQ 的配置文件来进行。打开 RabbitMQ 的配置文件(通常位于 /etc/rabbitmq/rabbitmq.conf 或 /etc/rabbitmq/rabbitmq-env.conf),添加以下配置项:

disk_free_limit.absolute = 1GB

这里的 1GB 表示磁盘剩余空间的阈值,当磁盘剩余空间小于 1GB 时,就会触发磁盘告警。

了解如何处理磁盘告警事件:

一旦磁盘使用量达到设定的磁盘告警阈值,RabbitMQ 会发出磁盘告警通知。处理磁盘告警事件的方式可以有以下几种:

  1. 增加磁盘空间: 如果 RabbitMQ 节点的磁盘使用量经常接近或超过磁盘告警阈值,说明节点的磁盘资源可能不足,可以考虑增加节点的磁盘空间来提高系统容量。
  2. 清理磁盘空间: 可以通过清理日志、临时文件或不必要的数据来释放磁盘空间,从而缓解磁盘告警情况。
  3. 数据迁移: 在集群环境中,如果某个节点的磁盘使用量持续高于磁盘告警阈值,可以考虑迁移该节点上的数据到其他节点上,从而平衡磁盘负载。
  4. 重启 RabbitMQ 节点: 在处理磁盘告警事件时,有时候简单的重启 RabbitMQ 节点也可以释放磁盘资源,缓解磁盘告警情况。

总之,设置合理的磁盘告警阈值,及时处理磁盘告警事件,可以帮助保障 RabbitMQ 的稳定运行和数据安全。根据具体的业务需求和资源情况,灵活调整磁盘告警阈值以及处理策略是非常重要的。

9.3 流控

了解流控的原理和使用方法,以确保队列的稳定性和可靠性。

9.3.1 流控的原理

流控(Flow Control)是一种在 RabbitMQ 中用于限制消息的传输速率的机制。它的主要目的是防止消息发送者向队列发送过多的消息,导致队列积压和系统资源耗尽。通过流控,可以使消息发送者在消息传输速率过快时自动降低发送速度,以适应接收端的处理能力。

流控的实现原理如下:

  1. 发送方控制: 流控是由消息发送方(生产者)实现的。当消息发送方向 RabbitMQ 发送消息时,RabbitMQ 会在队列的元数据中记录队列的剩余容量和消费者端的处理能力。
  2. Consumer Credit: RabbitMQ 使用 Consumer Credit 机制来跟踪队列上的消费者的处理能力。每个消费者都有一个 Credit 值,表示它还能从队列中取走多少消息。Credit 值会根据消费者处理消息的速率进行动态调整。
  3. Credit 消耗: 当消费者处理一条消息后,其 Credit 值会减少。如果 Credit 值为 0,则表示该消费者暂时不能从队列中取走更多消息,从而实现了流控。
  4. Credit 回复: 当消费者处理消息的速率下降(例如处理的消息较慢),RabbitMQ 会向消费者发送 Credit 回复,增加其 Credit 值,使其能够继续消费更多消息。
  5. Publisher Confirms: 流控在 RabbitMQ 中主要是基于 Publisher Confirms 机制实现的。在发送消息时,生产者可以选择等待 RabbitMQ 的确认,确认消息已经成功投递到队列中。当 RabbitMQ 发现队列的剩余容量不足时,会向生产者发送一个 Basic.Nack 消息,要求生产者暂停发送更多消息。

总结:流控是 RabbitMQ 中一种重要的机制,通过动态调整消费者的 Credit 值,它可以实现自适应的消息传输速率,防止消息发送速度过快导致队列积压。这种机制确保了 RabbitMQ 在高负载情况下的稳定性和可靠性。

9.3.2 案例:打破队列的瓶颈

通过流控机制,可以解决队列的瓶颈问题,提高消息处理的效率。流控机制可以帮助控制消息的传输速率,防止过多的消息堆积在队列中,导致队列积压和系统资源耗尽。

以下是通过流控机制来提高消息处理效率的步骤:

  1. 设置合理的流控阈值: 首先,需要根据系统的资源情况和处理能力,设置合理的流控阈值。流控阈值可以根据队列的大小、消费者的处理速率等因素进行调整。设置过大的阈值可能会导致队列积压,设置过小的阈值可能会导致消息发送速度受限。
  2. 监控队列状态: 实时监控队列的状态,包括队列的剩余容量、消费者的 Credit 值等信息。可以使用 RabbitMQ 的监控工具或者 API 接口来获取队列的状态信息。
  3. 动态调整流控阈值: 根据队列的实际情况,动态调整流控阈值。如果队列的剩余容量较大且消费者处理速率较快,可以适当放宽流控阈值,提高消息发送速率。如果队列的剩余容量较小或消费者处理速率较慢,可以收紧流控阈值,控制消息发送速率。
  4. 使用 Publisher Confirms: 在发送消息时,建议使用 Publisher Confirms 机制。Publisher Confirms 可以帮助生产者确认消息是否成功投递到队列中,从而更好地控制消息的发送速率。
  5. 优化消费者处理能力: 除了控制消息的发送速率,还可以优化消费者的处理能力,提高消息处理效率。例如,可以使用多个消费者并行处理消息,或者使用异步处理方式,以提高消息处理的吞吐量。

总之,通过合理设置流控阈值,动态调整阈值,监控队列状态和优化消费者处理能力,可以解决队列的瓶颈问题,提高消息处理的效率,保障 RabbitMQ 的稳定运行和可靠性。

9.4 镜像队列

镜像队列(Mirrored Queue)是 RabbitMQ 中用于提高消息的高可用性和数据冗余的一种机制。通过镜像队列,可以将队列的消息副本在多个节点上进行存储,当某个节点发生故障时,其他节点上的消息副本仍然可用,从而确保消息的不丢失和高可用性。

以下是镜像队列的概念和用法:

  1. 概念: 镜像队列是由 RabbitMQ 的集群中多个节点共同维护的队列。每个镜像队列都有一个主节点(Master)和多个镜像节点(Slave)。主节点负责接收消息,并将消息的副本复制到所有的镜像节点上。这样,当主节点发生故障时,消息仍然可以在镜像节点上被消费,从而实现高可用性和数据冗余。
  2. 配置: 要使用镜像队列,首先需要确保 RabbitMQ 集群已经正确搭建。然后,在创建队列时,需要设置队列的参数来使其成为镜像队列。通常,需要设置 x-ha-policy 参数为 all,表示将队列的消息复制到所有的节点上。示例代码如下:
Map<String, Object> args = new HashMap<>();
args.put("x-ha-policy", "all");
channel.queueDeclare("my_queue", true, false, false, args);
  1. 注意事项:
    • 镜像队列需要在 RabbitMQ 集群中的多个节点上进行复制,因此可能会增加集群节点之间的网络负载。要确保集群节点之间的网络连接良好,以避免消息复制的性能问题。
    • 镜像队列可以提高消息的高可用性,但仍然不能解决数据中心级别的故障。如果需要更高级别的可用性保障,可以考虑使用跨数据中心的镜像队列或者联邦队列等机制。

总结:镜像队列是 RabbitMQ 中实现消息高可用性和数据冗余的一种重要机制。通过在集群中的多个节点上复制消息的副本,可以确保消息在节点故障时不丢失,并提供更高的可用性保障。但要注意,镜像队列可能会增加网络负载和资源开销,需要根据具体的业务需求来选择使用。

9.5 小结

本章介绍了 RabbitMQ 的高阶特性,包括存储机制、内存及磁盘告警、流控、镜像队列等内容。在下一章中,我们将学习 RabbitMQ 网络分区的处理,以及如何处理网络分区的影响。

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

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

相关文章

【MySQL】数据去重,仅保留一条(效率最高)

系列文章 C#底层库–MySQLBuilder脚本构建类&#xff08;select、insert、update、in、带条件的SQL自动生成&#xff09; 本文链接&#xff1a;https://blog.csdn.net/youcheng_ge/article/details/129179216 C#底层库–MySQL数据库操作辅助类&#xff08;推荐阅读&#xff0…

一键生成logo的小妙招,这个方法值得收藏

在现代&#xff0c;每个品牌都需要一个标志性的logo&#xff0c;这个logo能够代表品牌&#xff0c;并且让消费者能够轻松识别出这个品牌。然而&#xff0c;对于许多人来说&#xff0c;制作一个漂亮的logo是一项艰巨的任务&#xff0c;需要花费大量的时间和精力。但是&#xff0…

2023 电赛E题--可能会出现的问题以及解决方法

2023年电赛E题报告模板&#xff08;K210版&#xff09;--可直接使用 本文链接&#xff1a;2023年电赛E题报告模板&#xff08;K210版&#xff09;--可直接使用_皓悦编程记的博客-CSDN博客 解决激光笔在黑色区域无法识别 本文链接&#xff1a; 2023 电赛 E 题 激光笔识别有误-…

W5500-EVB-PICO做DNS Client进行域名解析(四)

前言 在上一章节中我们用W5500-EVB-PICO通过dhcp获取ip地址&#xff08;网关&#xff0c;子网掩码&#xff0c;dns服务器&#xff09;等信息&#xff0c;给我们的开发板配置网络信息&#xff0c;成功的接入网络中&#xff0c;那么本章将教大家如何让我们的开发板进行DNS域名解析…

Python(六十三)获取字典视图

❤️ 专栏简介&#xff1a;本专栏记录了我个人从零开始学习Python编程的过程。在这个专栏中&#xff0c;我将分享我在学习Python的过程中的学习笔记、学习路线以及各个知识点。 ☀️ 专栏适用人群 &#xff1a;本专栏适用于希望学习Python编程的初学者和有一定编程基础的人。无…

设计模式行为型——中介者模式

目录 什么是中介者模式 中介者模式的实现 中介者模式角色 中介者模式类图 中介者模式代码实现 中介者模式的特点 优点 缺点 使用场景 注意事项 实际应用 什么是中介者模式 中介者模式&#xff08;Mediator Pattern&#xff09;属于行为型模式&#xff0c;是用来降低…

Filebeat+ELK 部署

Node1节点&#xff08;2C/4G&#xff09;&#xff1a;node1/192.168.8.10 Elasticsearch Kibana Node2节点&#xff08;2C/4G&#xff09;&#xff1a;node2/192.168.8.11 Elasticsearch Apache节点&#xff1a;apache/192.168.8.13 …

Java反射学习(大综合)

第一天 Java反射及动态代理... 2 一、 Java反射... 2 1、什么是反射&#xff1a;... 2 2、反射的原理... 2 3、反射的优缺点&#xff1a;... 2 4、反射的用途&#xff1a;... 3 5、反射机制常用的类&#xff1a;... 3 1、获得Class&#xff1a;主要有三…

计算机基础:数据库-Sqlserver

数据库-Sqlserver 前言参考链接&#xff1a;关键词数据库代码案例视图触发器索引窗口函数游标小记 前言 妥妥的复习&#xff0c;我相信chatjpt,也相信笔记。 说实话&#xff0c;真正碰到问题还是先想到搜索引擎或chatjpt&#xff08;即使印象中自己的笔记记过相关内容&#xf…

NVIDIA 535.86.05 Linux 图形驱动程序改进 Wayland 支持

导读NVIDIA公司近日发布了适用于 Linux、FreeBSD 和 Solaris 系统的 NVIDIA 535.86.05 图形驱动程序&#xff0c;作为其生产分支的维护更新&#xff0c;解决了各种错误和问题。 NVIDIA 535.86.05 是在 NVIDIA 535.54.03 发布一个多月之后发布的&#xff0c;它通过解决在使用某…

量子机器学习解决方案新鲜出炉!Rigetti和ADIALab签署合作

​ &#xff08;图片来源&#xff1a;网络&#xff09; 近日&#xff0c;美国全栈量子经典计算的先驱Rigetti Computing宣布与阿拉伯联合酋长国的ADIA Lab签署了合作协议&#xff0c;双方将共同设计、构建、运行和优化量子计算解决方案&#xff0c;旨在解决概率分布分类问题&am…

【腾讯云Cloud Studio实战训练营】如何成为一名合格的Python爬虫“念咒师”(基于ChatGpt)

【前言】 不管是新手程序猿&#xff0c;还是秃头程序猿&#xff0c;在工作学习中&#xff0c;都无法避免一项看似简单却又异常重要的环节——搭建开发环境&#xff0c;这常常让我们程序猿们头痛不已&#xff01;毫不夸张的说&#xff0c;它可能是整个开发过程中最具挑战性和耗时…

Xcode protobuf2.5添加arm64编译器补丁生成静态库

项目需求&#xff0c;protobuf源码编成静态库使用 但是&#xff0c;github上的protobuf源码没有对应arm64的编译器定义&#xff0c;编译出来的静态库使用时报错。 下面的连接是arm64编译器代码补丁包&#xff0c;把编译器代码放到src/google/protobuf/stubs/atomicops_intern…

【安装】阿里云轻量服务器安装Ubuntu图形化界面(端口号/灰屏问题)

阿里云官网链接 https://help.aliyun.com/zh/simple-application-server/use-cases/use-vnc-to-build-guis-on-ubuntu-18-04-and-20-04 网上搜了很多教程&#xff0c;但是我没在界面看到有vnc连接&#xff0c;后面才发现官网有教程。 其实官网很详细了&#xff0c;不过这里还是…

Golang空结构体struct{}的作用是什么?

文章目录 占位符&#xff1a;通道标识&#xff1a;键集合&#xff1a;内存占用优化&#xff1a;总结&#xff1a; 在Go语言中&#xff0c;空结构体 struct{}是一种特殊的数据类型&#xff0c;它不占用任何内存空间。空结构体没有任何字段&#xff0c;也没有任何方法。尽管它看起…

Android Studio 的Gradle版本修改

使用Android Studio构建项目时&#xff0c;需要配置Gradle&#xff0c;与Gradle插件。 Gradle是一个构建工具&#xff0c;用于管理和自动化Android项目的构建过程。它使用Groovy或Kotlin作为脚本语言&#xff0c;并提供了强大的配置能力来定义项目的依赖关系、编译选项、打包方…

gradio创建机器学习的好工具 基本使用和示例

1.gradio介绍 Gradio: 用Python构建机器学习网页APP Gradio是一个开源的Python库,用于构建演示机器学习或数据科学,以及web应用程序。 使用Gradio,您可以基于您的机器学习模型或数据科学工作流快速创建一个漂亮的用户界面,让用户可以”尝试“拖放他们自己的图像、粘贴文本…

飞凌嵌入式「国产」平台大盘点(二)全志系列

在上篇文章中&#xff0c;小编带大家一起盘点了飞凌嵌入式国产平台中的瑞芯微系列核心板。本篇文章&#xff0c;将继续为大家介绍的是全志系列核心板&#xff0c;话不多说&#xff0c;上干货&#xff01; 全志科技 飞凌嵌入式 飞凌嵌入式与全志科技的合作始于2019年&#xff…

MobPush iOS SDK iOS实时活动

开发工具&#xff1a;Xcode 功能需要: SwiftUI实现UI页面&#xff0c;iOS16.1以上系统使用 功能使用: 需应用为启动状态 功能说明 iOS16.1 系统支持实时活动功能&#xff0c;可以在锁定屏幕上实时获知各种事情的进展&#xff0c;MobPushSDK iOS 4.0.3版本已完成适配&#xf…

Webpack5新手入门简单配置

1.初始化项目 yarn init -y 2.安装依赖 yarn add -D webpack5.75.0 webpack-cli5.0.0 3.新建index.js 说明&#xff1a;写入下面的一句话 console.log("hello webpack"); 4.执行命令 说明&#xff1a;如果没有安装webpack脚手架就不能执行yarn webpack&#xff08…