【面试】消息中间件 Rabbit MQ

35 篇文章 1 订阅
1 篇文章 0 订阅

 

1、为什么使用RabbitMQ?

      RabbitMQ是一款开源的,Erlang编写的,基于AMQP协议的,消息中间件;

优点

  • 流量削峰,高并发缓存 消息缓冲
  • 消息分发
  • 应用解耦(系统拆分,分布式解耦)
  • 异步处理(预约挂号业务处理成功后,异步发送短信、推送消息、日志记录等)

缺点

  • 系统可用性降低(MQ中间件突然挂掉)
  • 系统稳定性降低(消息丢失
  • 分布式一致性问题 ()

 

2、消息怎么路由?

消息路由有三部分:交换机、路由、绑定

生产者把消息发布到交换机上;

绑定决定了消息如何从路由到特定的队列;

消息最终到达队列,并被消费者接收。

 

交换机主要有三种

direct 

一对一

如果消息中路由键【routing key】和Binding中的【binding key】一致,完全匹配,交换机就将消息发到对应的队列中。单播模式。分发策略:轮询分发(平均分发);公平分发(按消费能力分发,消费完毕一个再分发一个,不会堵塞);

fanout

一对多

每个发到fonout类型交换机的消息,都会分到所有绑定的队列上去。每台子网的主机都获得一份复制的消息。

广播模式。转发消息的最快的。

topic

一对多

可以使来自不同源头的消息能够到达同一个队列。 使用topic交换器时,可以使用通配符,比如:“*” 匹配特定位置的任意文本, “.” 把路由键分为了几部分,“#” 匹配所有规则等。特别注意:发往topic交换器的消息不能随意的设置选择键(routing_key),必须是由"."隔开的一系列的标识符组成。

3、如何保证RabbitMQ不被重复消费?

  为什么会重复消费:

正常情况下,消费者在消费消息的时候,消费完毕会发生一个确认消息给消息队列,消息队列确认消息已被消费,就会从消息队列里删掉该消息。但是因为网络传输等等故障,确认消息没有发送到消息队列,导致消息队列无法知道这条消息是否被消费成功了,就会再次发送这个“未被消费”的消息。

解决 ==》

保证消息的唯一性,就算是多次传输,不要让消息的多次消费带来影响,保证消费幂等性;

比如,在写入消息队列的数据做唯一标识,消费消息时候,根据唯一标识判断是否被消费过。

1.当拿到这个消息做数据库的insert操作。那就容易了,给这个消息做一个唯一主键,那么就算出现重复消费的情况,就会导致主键冲突,避免数据库出现脏数据。

2.当拿到这个消息做redis的set的操作,那就容易了,不用解决,因为你无论set几次结果都是一样的,set操作本来就算幂等操作。
3.如果上面两种情况还不行,准备一个第三方存储,来做消费记录。以redis为例,给消息分配一个全局id,只要消费过该消息,将<id,message>以K-V形式写入redis。那消费者开始消费前,先去redis中查询有没消费记录即可。

 

4、如何保证RabbitMQ消息的可靠传输?

        消息不可靠的情况可能是消息丢失,劫持等原因;

         丢失又分为:生产者丢失消息、消息列表丢失消息、消费者丢失消息;

生产者丢失

从生产者角度丢失数据,RabbitMQ 提供两种模式保证数据不丢失 ,transaction 和 confirm 。

transaction机制发送消息前,开启事务(channel.txSelect()),然后发送消息,如果发送过程出现异常,事务就回滚(channel.txRollback()。如果发送成功,则提交事务(channel.txCommit())。缺点:吞吐量下降。
confirm模式用的居多,一旦channel进入confirm模式,所有在该信道上发布的消息都将会被指派一个唯一的ID(从1开始),一旦消息被投递到所有匹配的队列上,rabbitMQ就会发送一个ACK给生产者(包括唯一ID),就这使得生产者得知消息已经正确到达目的队列。如果rabbitMQ没能处理该消息,则会发送一个Nack消息给你,你可以重试操作。

消息队列丢失:

处理消息队列丢失数据的情况,一般是开启持久化磁盘的配置。持久化配置和confirm机制配合使用,你可以在消息持久化磁盘后,再给生产者发送一个ACK信号。如果消息持久化之前,rabbitMQ崩溃了,那么生产者收不到ACK信号,就会自动重发。

1.将queue的持久化标识durable 设置为true ,则代表是一个持久化队列。

2.发送消息的时候 将deliveryMode =2。即使rabbitMQ挂了,重启后也能恢复数据。

 

消费者丢失:

消费者丢数据一般是因为采用了自动确认消息模式,改为手动确认消息。

消费者在收到消息后,处理消息之前,会自动回复rabbitMQ已收到消息。如果这时处理消息失败,就会丢失消息。

解决 ==》 处理消息成功后,手动回复确认消息。

 

5、如何保证RabbitMQ 消息的顺序性

单线程消费保证消息的顺序性,对消息进行编号,消费者处理消息是根据编号处理消息。

 

ref

activeMQ面试总结   https://blog.csdn.net/bird73/article/details/79835457

RabbitMQ几个常用面试题  https://www.cnblogs.com/woadmin/p/10537174.html

https://www.jianshu.com/p/eaafb1581e55

消息中间件面试题:消息队列的优缺点,区别       https://blog.csdn.net/wqc19920906/article/details/82193316

面试官问你什么是消息队列?把这篇甩给他!

哥们,你们的系统架构中为什么要引入消息中间件?

【Java进阶面试系列之二】:哥们,那你说说系统架构引入消息中间件有什么缺点?【石杉的架构笔记】

高并发架构消息队列面试题解析 

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值