【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 的完整数据。

相关推荐
Saltwater_leo21 分钟前
【无标题】
java·服务器·前端
爱吃喵的鲤鱼34 分钟前
Linux——线程条件变量(同步)
java·开发语言
lhhbk37 分钟前
力扣面试经典题
算法·leetcode·面试
东小黑39 分钟前
java方法以及与C语言对比学习
java·c语言·学习
黄雪超39 分钟前
Java面试专题——面向对象
java·面试·面向对象
007php0071 小时前
go语言zero框架通过chromedp实现网页在线截图的设计与功能实现
java·开发语言·后端·python·docker·云原生·golang
寒山李白1 小时前
MySQL入门(数据库、数据表、数据、字段的操作以及查询相关sql语法)
java·数据库·sql·mysql
蚂蚁质量1 小时前
什么是 Java 虚拟机(JVM)?
java·开发语言·jvm
日拱一卒无有尽, 功不唐捐终入海2 小时前
Mybatis乐观锁使用
java·开发语言·jvm·mybatis
青柚~2 小时前
【Idea启动项目报错NegativeArraySizeException】
java·ide·intellij-idea