【Java面试】RabbitMQ

RabbitMQ是什么?

RabbitMQ是一款开源的、基于Erlang语言编写的消息中间件,遵循AMQP协议(Advanced Message Queuing Protocol )。

RabbitMQ核心概念

生产者(Producer):发送消息的一方。

消费者(Consumer):接收消息的一方。

消息队列(Queue):存储消息的容器,消息最终被发送到这里。

交换器(Exchange):负责将消息路由到队列,根据绑定规则转发消息。

绑定(Binding):将交换器和队列关联起来的路由规则。

Broker:RabbitMQ 的服务节点,可以看作一个 RabbitMQ 服务器。

交换器类型

fanout:广播消息到所有绑定的队列,不关心路由键。

direct:根据路由键完全匹配转发消息。

topic :支持模糊匹配(* 匹配一个单词,# 匹配多个单词)。

headers:根据消息头中的键值对匹配,较少使用。

消息可靠性

生产者到 RabbitMQ

  • 事务机制(tx):效率低,不推荐。

  • Confirm 机制:生产者确认消息是否成功到达 Broker。

RabbitMQ 内部

  • 持久化(durable):将消息存储到磁盘。

  • 集群和镜像队列:保证高可用性。

RabbitMQ 到消费者

  • 消费者确认(basicAck):确保消息被正确消费。

  • 死信队列(DLX):处理未被消费的消息。

什么是死信队列?如何导致的?

DLX,全称为 Dead-Letter-Exchange,死信交换器。当消息在一个队列中变成死信 (dead message) 之后,它能被重新发送到另一个交换器中,这个交换器就是 DLX,绑定 DLX 的队列就称之为死信队列。

导致的死信的几种原因

  • 消息被拒(Basic.Reject /Basic.Nack) 且 requeue = false
  • 消息 TTL 过期。
  • 队列满了,无法再添加。

延迟队列

  • 使用 TTL(消息存活时间)和死信交换器(DLX)实现。

  • 插件支持(rabbitmq-delayed-message-exchange)。一般使用这种方式。

如何保证RabbitMQ高可用?

RabbitMQ 是比较有代表性的,因为是基于主从(非分布式)做高可用性的,我们就以 RabbitMQ 为例子讲解第一种 MQ 的高可用性怎么实现。RabbitMQ 有三种模式:单机模式、普通集群模式、镜像集群模式。

单机模式

Demo 级别的,一般就是你本地启动了玩玩儿的?,没人生产用单机模式。

普通集群模式

意思就是在多台机器上启动多个 RabbitMQ 实例,每个机器启动一个。你创建的 queue,只会放在一个 RabbitMQ 实例上,但是每个实例都同步 queue 的元数据(元数据可以认为是 queue 的一些配置信息,通过元数据,可以找到 queue 所在实例)。

你消费的时候,实际上如果连接到了另外一个实例,那么那个实例会从 queue 所在实例上拉取数据过来。这方案主要是提高吞吐量的,就是说让集群中多个节点来服务某个 queue 的读写操作。

镜像集群模式

这种模式,才是所谓的 RabbitMQ 的高可用模式。跟普通集群模式不一样的是,在镜像集群模式下,你创建的 queue,无论元数据还是 queue 里的消息都会存在于多个实例上,就是说,每个 RabbitMQ 节点都有这个 queue 的一个完整镜像,包含 queue 的全部数据的意思。然后每次你写消息到 queue 的时候,都会自动把消息同步到多个实例的 queue 上。RabbitMQ 有很好的管理控制台,就是在后台新增一个策略,这个策略是镜像集群模式的策略,指定的时候是可以要求数据同步到所有节点的,也可以要求同步到指定数量的节点,再次创建 queue 的时候,应用这个策略,就会自动将数据同步到其他的节点上去了。

这样的好处在于,你任何一个机器宕机了,没事儿,其它机器(节点)还包含了这个 queue 的完整数据,别的 consumer 都可以到其它节点上去消费数据。坏处在于,第一,这个性能开销也太大了吧,消息需要同步到所有机器上,导致网络带宽压力和消耗很重!RabbitMQ 一个 queue 的数据都是放在一个节点里的,镜像集群下,也是每个节点都放这个 queue 的完整数据。

相关推荐
黎雁·泠崖19 小时前
Java面向对象:this关键字+构造方法+标准JavaBean
java·开发语言·python
sheji341619 小时前
【开题答辩全过程】以 基于Java的智慧环卫垃圾收运管理系统设计与实现为例,包含答辩的问题和答案
java·开发语言
jason成都19 小时前
实战 | 国产数据库 R2DBC-JDBC 桥接踩坑记 - JetLinks适配达梦数据库
java·数据库·物联网
BullSmall19 小时前
SEDA (Staged Event-Driven Architecture, 分阶段事件驱动架构
java·spring·架构
Coder_Boy_20 小时前
基于SpringAI的在线考试系统-DDD(领域驱动设计)核心概念及落地架构全总结(含事件驱动协同逻辑)
java·人工智能·spring boot·微服务·架构·事件驱动·领域驱动
黎雁·泠崖20 小时前
Java&C语法对比:分支与循环结构核心全解析
java·c语言
鹿角片ljp20 小时前
Java IO流案例:使用缓冲流恢复《出师表》文章顺序
java·开发语言·windows
毕设源码-郭学长20 小时前
【开题答辩全过程】以 广告投放管理系统为例,包含答辩的问题和答案
java
小北方城市网20 小时前
SpringBoot 集成 RabbitMQ 实战(消息队列解耦与削峰):实现高可靠异步通信
java·spring boot·python·微服务·rabbitmq·java-rabbitmq·数据库架构
java_t_t21 小时前
Maven插件apiscan介绍与使用
java·maven·api文档·maven插件