欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 科技 > IT业 > 消息中间件常见面试题(RabbitMQ)

消息中间件常见面试题(RabbitMQ)

2024/10/25 7:22:28 来源:https://blog.csdn.net/qq_69183322/article/details/142487892  浏览:    关键词:消息中间件常见面试题(RabbitMQ)

MQ场景:

  • 异步发送(验证码、短信、邮件)
  • MySQL、Redis、ES之间的数据同步
  • 分布式事务等

一、RabbitMQ

1.1 消息不丢失

提问:如果保证消息不丢失呢?

流程:生产者将消息发送给交换机,交换机发送给指定的消息队列中,消费者再从消息队列中取出消息

(1) 消息丢失的原因:

1. 生产者发送给交换机的过程中就丢失了消息,

2. 交换机发送到指定的队列中消息丢失了,

3. 消费者还没来得及消费消息的过程中丢失消息。

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

(2) 消息发送失败的后处理方式:

  • 回调方法即时重发
  • 记录日志
  • 保存到数据库然后定时重发,成功发送后即刻删除表中的数据

 

(3) 开启消息持久化

因为MQ默认是内存存储消息,重启或者宕机会导致消息的丢失,所以要开启消息持久化的功能,保证缓存在MQ中的消息不丢失

1.交换机持久化

2.队列持久化

3.消息持久化

(4) 消费者确认

RabbitMQ支持消费者确认机制,即:消费者处理消息后可以向MQ发送ack回执,MQ收到ack回执后才会删除该消息(也就是确保消费者消息了消息,才从消息将消息队列中对应的消息删除)

SpringAMQP的配置三种确认模式:

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

利用Spring的retry机制,在消费者出现异常时进行本地重试,设置重试次数,当次数达到之后,如果消息任然失败,则将消息投递到异常交换机,由人工处理。

1.2 消息重复消费

当服务发送网络问题或服务宕机导致出现RabbiMQ消息的重复消费问题

解决方案:

给每条消息设置唯一的标识

幂等方案有分布式锁、数据库锁(悲观锁、乐观锁)

1.3 消息堆积 

当生产者生成消息的速度大于消费者消费消息的速度,就会导致队列中的消息堆积,直到队列存储消息达到上限,之后发送的消息就会成为死信,可能会被丢弃,这就是消息堆积问题。

解决消息堆积的三种思路:

  • 增加更多的消费者,提高消费速度
  • 在消费者内开启线程池加快消息处理速度
  • 扩大队列容器,提高堆积上限,采用惰性队列

惰性队列

  • 接收到消息后直接存入磁盘而非内存
  • 消费者要消费消息时才会从磁盘中读取并加载到内存
  • 支持数百万条的消息存储

1.4 延迟队列(死信队列)

延迟队列:进入队列的消息会被延迟消费的队列

场景:超时订单、限时优惠、定时发布

延时队列 相当于 死信交换机 + TTL(生存时间)

消息超时未消费都会进入死信队列中,再通过对死信队列中的消息进行消费

1.5 高可用机制

RabbitMQ的镜像队列功能允许队列在不同的节点上拥有多个副本。如果主节点发生故障,一个副本可以自动升级为新的主节点。在主从同步完成之前,主节点就已经宕机,可能出现数据丢失。

出现数据丢失如何解决呢?

我们可以采用仲裁队列,与镜像队列一样,都是主从模式,支持主从数据同步,主从同步基于Raft协议,强一致性。

使用方式:

只需要在声明队列时指定这个是仲裁队列即可。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com