05-RabbitMQ 面试题

目录

目录

1.RabbitMQ-如何保证消息不丢失?

2.RabbitMQ消息的重复消费问题如何解决的?

3.RabbitMQ中死信交换机 ? (RabbitMQ延迟队列有了解过嘛)

4.RabbitMQ如果有100万消息堆积在MQ , 如何解决(消息堆积怎么解决)

5.RabbitMQ的高可用机制有了解过嘛

6.RabbitMQ如何保证消息的有序性?

7.RabbitMQ有哪些消息处理模式(订阅模式或工作模式)?



1.RabbitMQ-如何保证消息不丢失?

消息中间件的好处

  1. 提供了系统之间的异步调用,让服务与服务之间解耦
  2. 削峰、填谷

场景:

  1. 异步发送(验证码、短信、邮件…)
  2. MySQL和Redis , ES之间的数据同步
  3. 分布式事务
  4. 削峰填谷

消息发送者(publisher )把消息发送给交换机(exchange),由交换机路由到队列,最后由消费者(consumer)进行消费消息。

出现消息丢失的四种情况:

  1. 消息未到达交换机
  2. 消息未到达队列
  3. 队列中消息丢失
  4. 消费者未接收到消息

生产者确认机制(解决消息未到达交换机、消息未到达队列问题

RabbitMQ提供了publisher confirm机制来避免消息发送到MQ过程中丢失。消息发送到MQ以后,会返回一个结果(ack)给发送者,表示消息是否处理成功

如果消息发送失败,有两种情况:

  1. 消息到达交换机失败(publisher-confirm nack
  2. 交换机路由到队列失败(publisher-return ack

消息失败之后如何处理呢?

  1. 回调方法即时重发(知道哪一个消息发送失败,可以再发)
  2. 记录日志(如果还是发送失败,可以记录日志,通过查看日志进行补偿)
  3. 保存到数据库然后定时重发,成功发送后即刻删除表中的数据 

如果重发失败了怎么办?

  1. 一般消息发送失败了,很大几率是服务提供者宕机了或者是MQ宕机了,这两者不可能一直处于宕机状态。
  2. 如果还是不能解决,需要人工来解决这些问题

消息已经正常发送到队列,但是MQ 宕机了,也会导致消息丢失,该怎么解决?

消息持久化(解决队列中消息丢失问题
MQ默认是内存存储消息,开启持久化功能可以确保缓存在MQ中的消息不丢失。(MQ宕机或重启后,在内存中的消息肯定会丢失,需要持久化
1.交换机持久化:

@Bean
public DirectExchange simpleExchange(){  
// 三个参数:交换机名称、是否持久化、当没有queue与其绑定时是否自动删除
return new DirectExchange("simple.direct", true, false);
}

2.队列持久化:

@Bean 
public Queue simpleQueue(){     
// 使用QueueBuilder构建队列,durable就是持久化的     
return QueueBuilder.durable("simple.queue").build(); 
}

3.消息持久化,SpringAMQP中的的消息默认是持久的,可以通过MessageProperties中的DeliveryMode来指定的:

Message msg = MessageBuilder
.withBody(message.getBytes(StandardCharsets.UTF_8)) //消息体
.setDeliveryMode(MessageDeliveryMode.PERSISTENT) //持久化
.build();

消费者确认(解决消费者未接收到消息问题

RabbitMQ支持消费者确认机制,即:消费者处理消息后可以向MQ发送ack回执,MQ收到ack回执后才会删除该消息。而SpringAMQP(RabbitMQ+Spring整合)则允许配置三种确认模式:

  • manual:手动ack,需要在业务代码结束后,调用api发送ack。
  • auto:自动ack,由spring监测listener代码是否出现异常,没有异常则返回ack;抛出异常则返回nack(当消息者处理完消息之后,会判断中间是否存在异常,如果没有异常是正常消费)
  • none:关闭ack,MQ假定消费者获取消息后会成功处理,因此消息投递后立即被删除

一般我们会选择auto 作为确认机制,假如消费者接受消息失败了,那该怎么办?

我们可以利用Spring的retry机制,在消费者出现异常时利用本地重试,设置重试次数,当次数达到了以后,如果消息依然失败,将消息投递到异常交换机,交由人工处理

总结:

  1. 确认消息要消费,发送一个ack,一般采用自动确认机制
  2. 设置重试机制,重试机制不是无限次的,设置一个重试次数,如果达到这个重试次数之后,将消息投递到异常交换机,交由人工处理

RabbitMQ-如何保证消息不丢失?

  1. 开启生产者确认机制,确保生产者的消息能到达队列
  2. 开启持久化功能,确保消息未消费前在队列中不会丢失
  3. 开启消费者确认机制为auto,由spring确认消息处理成功后完成ack
  4. 开启消费者失败重试机制,多次重试失败后将消息投递到异常交换机,交由人工处理

面试参考回答:

面试官:RabbitMQ-如何保证消息不丢失

候选人:

嗯!我们当时MYSQL和Redis的数据双写一致性就

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值