Java面试——RabbitMQ系列总结
Posted 张起灵-小哥
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java面试——RabbitMQ系列总结相关的知识,希望对你有一定的参考价值。
文章目录:
9.交换机无法根据自身类型和路由键找到符合条件队列时,有哪些处理方法?
1.RabbitMQ是什么?
RabbitMQ是一款开源的,Erlang编写的,基于AMQP(高级消息队列协议)协议的消息中间件。
2.为什么要使用消息队列?
从本质上来说是因为互联网的快速发展,业务不断扩张,促使技术架构需要不断的演进。
从以前的单体架构到现在的微服务架构,成百上千的服务之间相互调用和依赖。从互联网初期一个服务器上有 100 个在线用户已经很了不得,到现在坐拥10亿日活的微信。此时,我们需要有一个「工具」来解耦服务之间的关系、控制资源合理合时的使用以及缓冲流量洪峰等等。因此,消息队列就应运而生了。
它常用来实现:
异步处理
、服务解耦
、流量控制(削峰)
。
3.说说RabbitMQ中的几大组件
- Broker:接收和分发消息的应用,RabbitMQ Server 就是 Message Broker。
- Virtual host:出于多租户和安全因素设计的,把 AMQP 的基本组件划分到一个虚拟的分组中,类似于网络中的 namespace 概念。当多个不同的用户使用同一个 RabbitMQ server 提供的服务时,可以划分出多个 vhost,每个用户在自己的 vhost 创建 exchange/queue 等。
- Connection:publisher/consumer 和 broker 之间的 TCP 连接Channel:如果每一次访问 RabbitMQ 都建立一个 Connection,在消息量大的时候建立 TCP Connection 的开销将是巨大的,效率也较低。Channel 是在 connection 内部建立的逻辑连接,如果应用程序支持多线程,通常每个 thread 创建单独的 channel 进行通讯,AMQP method 包含了 channel id 帮助客户端和 message broker 识别 channel,所以 channel 之间是完全隔离的。 l Channel 作为轻量级的Connection 极大减少了操作系统建立 TCP connection 的开销。
- Exchange : message 到达 broker 的第一站,根据分发规则,匹配查询表中的 routing key,分发消息到 queue 中去。常用的类型有:direct (point-to-point), topic (publish-subscribe) and fanout(multicast)。
- Queue : 消息最终被送到这里等待 consumer 取走。
- Binding : exchange 和 queue 之间的虚拟连接,binding 中可以包含 routing key,Binding 信息被保存到 exchange 中的查询表中,用于 message 的分发依据。
- Producer:消息生产者,就是投递消息的一方。消息一般包含两个部分:消息体(
payload
)和标签(Label
)。- Consumer:消费消息,也就是接收消息的一方。消费者连接到RabbitMQ服务器,并订阅到队列上。消费消息时只消费消息体,丢弃标签。
4.消息队列有什么优缺点?
优点上面已经说了,就是在特殊场景下有其对应的好处,解耦、异步、削峰。缺点有以下几个:
系统可用性降低:系统引入的外部依赖越多,越容易挂掉。万一 MQ 挂了,MQ 一挂,整套系统崩 溃,你不就完了?
系统复杂度提高:硬生生加个 MQ 进来,你怎么保证消息没有重复消费?怎么处理消息丢失的情况?
怎么保证消息传递的顺序性?问题一大堆。
一致性问题:A 系统处理完了直接返回成功了,人都以为你这个请求就成功了;但是问题是,要是 BCD 三个系统那里,BD 两个系统写库成功了,结果 C 系统写库失败了,咋整?你这数据就不一致 了。
5.如何保证消息的可靠性?
消息到MQ的过程中搞丢,MQ自己搞丢,MQ到消费过程中搞丢。
生产者到RabbitMQ
:事务机制和Confirm机制,注意:事务机制和 Confirm 机制是互斥的,两者不能共存,会导致 RabbitMQ 报错。
RabbitMQ自身
:持久化、集群、普通模式、镜像模式。
RabbitMQ到消费者
:basicAck机制、死信队列、消息补偿机制。
6.RabbitMQ中常见交换机类型有哪些?
fanout:把所有发送到该交换器的消息路由到所有与该交换器绑定的队列中。
direct:把消息路由到BindingKey和RoutingKey完全匹配的队列中。
topic:
RoutingKey
为一个 点号'.': 分隔的字符串。比如:szh.name.love
BindingKey
和RoutingKey
一样也是点号“.“分隔的字符串。
BindingKey
可使用 * 和 # 用于做模糊匹配,*匹配一个单词,#匹配多个或者0个
7.生产者发送消息的过程是怎样的?
Producer
先连接到Broker,建立连接Connection,开启一个信道(Channel)。Producer
声明一个交换器并设置好相关属性。Producer
声明一个队列并设置好相关属性。Producer
通过路由键将交换器和队列绑定起来。Producer
发送消息到Broker
,其中包含路由键、交换器等信息。- 相应的交换器根据接收到的路由键查找匹配的队列。
- 如果找到,将消息存入对应的队列,如果没有找到,会根据生产者的配置丢弃或者退回给生产者。
- 关闭信道,关闭连接。
8.消费者接收消息的过程是怎样的?
Producer
先连接到Broker
,建立连接Connection,
开启一个信道(Channel
)。- 向
Broker
请求消费响应的队列中的消息,可能会设置响应的回调函数。- 等待
Broker
回应并投递相应队列中的消息,接收消息。- 消费者确认收到的消息,
ack
。RabbitMQ
从队列中删除已经确定的消息。- 关闭信道,关闭连接。
9.交换机无法根据自身类型和路由键找到符合条件队列时,有哪些处理方法?
mandatory :true 返回消息给生产者。
mandatory : false 直接丢弃。
10.什么是死信队列?导致死信的原因有哪些?
死信,DLX,全称为
Dead-Letter-Exchange
,死信交换器,死信邮箱。顾名思义就是无法被消费的消息,一般来说,producer 将消息投递到 broker 或者直接到 queue 里了,consumer 从 queue 取出消息进行消费,但某些时候由于特定的原因导致 queue 中的某些消息无法被消费,这样的消息如果没有后续的处理,就变成了死信,有死信自然就有了死信队列。
- 消息 TTL 过期
- 队列达到最大长度 (队列满了,无法再添加数据到 mq 中)
- 消息被拒绝 (basic.reject 或 basic.nack) 并且 requeue=false.
11.什么是延迟队列?使用场景有哪些?
存储对应的延迟消息,指当消息被发送以后,并不想让消费者立刻拿到消息,而是等待特定时间后,消费者才能拿到这个消息进行消费。
- 订单在十分钟之内未支付则自动取消。
- 新创建的店铺,如果在十天内都没有上传过商品,则自动发送消息提醒。
- 用户注册成功后,如果三天内没有登陆则进行短信提醒。
- 用户发起退款,如果三天内没有得到处理则通知相关运营人员。
- 预定会议后,需要在预定的时间点前十分钟通知各个与会人员参加会议
12.什么是优先级队列?
优先级高的队列会先被消费。
可以通过
x-max-priority
参数来实现。当消费速度大于生产速度且Broker没有堆积的情况下,优先级显得没有意义。
13.RabbitMQ中的事务机制?
RabbitMQ 客户端中与事务机制相关的方法有三个:
channel.txSelect
用于将当前的信道设置成事务模式。
channel.txCommit
用于提交事务 。
channel.txRollback
用于事务回滚,如果在事务提交执行之前由于 RabbitMQ 异常崩溃或者其他原因抛出异常,通过txRollback来回滚。
14.RabbitMQ中的发送确认机制?
生产者将信道设置成 confirm 模式,一旦信道进入 confirm 模式, 所有在该信道上面发布的消息都将会被指派一个唯一的 ID(从 1 开始),一旦消息被投递到所有匹配的队列之后,broker就会发送一个确认给生产者(包含消息的唯一 ID),这就使得生产者知道消息已经正确到达目的队列了。
15.如何保证RabbitMQ消息队列的高可用?
RabbitMQ 有三种模式:
单机模式
,普通集群模式
,镜像集群模式
。单机模式:就是demo级别的,一般就是你本地启动了玩玩儿的,没人生产用单机模式
普通集群模式:意思就是在多台机器上启动多个RabbitMQ实例,每个机器启动一个。
镜像集群模式:这种模式,才是所谓的RabbitMQ的高可用模式,跟普通集群模式不一样的是,你创建的queue,无论元数据(元数据指RabbitMQ的配置数据)还是queue里的消息都会存在于多个实例上,然后每次你写消息到queue的时候,都会自动把消息到多个实例的queue里进行消息同步。
以上是关于Java面试——RabbitMQ系列总结的主要内容,如果未能解决你的问题,请参考以下文章
2021年Java程序员面试精选系列:RabbitMQ+Zookeeper+Redis+JVM