MST

星途 面试题库

面试题:消息队列在消息推送服务中的一致性与可靠性保障

在使用消息队列实现消息推送服务时,如何确保消息的一致性和可靠性?请结合具体的消息队列产品(如Kafka、RabbitMQ等),从消息的生产、存储、消费等环节详细阐述相关的机制和技术手段。
32.7万 热度难度
后端开发消息队列

知识考点

AI 面试

面试题答案

一键面试

Kafka

  1. 消息生产
    • acks参数:生产者发送消息时可设置acks参数。acks=0表示生产者发送消息后不需要等待任何确认,消息可能丢失;acks=1表示生产者等待Leader副本确认,若Leader副本在确认前崩溃,消息可能丢失;acks=all(或acks=-1)表示生产者等待ISR(In-Sync Replicas,与Leader保持同步的副本集合)中所有副本确认,此时消息可靠性最高,基本不会丢失,但可能影响性能。
    • 重试机制:生产者发送消息失败时,会按照配置的重试次数和重试间隔进行重试,以确保消息成功发送到Kafka集群。
  2. 消息存储
    • 多副本机制:Kafka采用多副本机制,每个分区有一个Leader副本和多个Follower副本。Leader负责处理读写请求,Follower定期从Leader同步数据。当Leader出现故障时,Kafka会从Follower中选举新的Leader,保证数据的可用性和一致性。
    • ISR动态调整:ISR集合会动态调整,若Follower副本与Leader副本的滞后时间或滞后消息数超过一定阈值,该Follower会被移出ISR;当Follower追上Leader时,又会被重新加入ISR。只有ISR中的副本才会参与消息的同步和选举,保证数据一致性。
  3. 消息消费
    • 位移管理:消费者通过偏移量(offset)记录已消费的消息位置。Kafka提供了自动提交和手动提交两种方式。自动提交简单方便,但可能会导致重复消费;手动提交由消费者控制偏移量的提交时机,可保证消息的准确消费,避免重复消费和消息丢失。
    • Exactly-Once语义:Kafka 0.11.0.0版本引入了Exactly-Once语义,通过Producer ID(PID)和Sequence Number实现。每个Producer在初始化时会被分配一个PID,每次发送消息时会携带一个Sequence Number,Kafka通过检查PID和Sequence Number保证消息仅被处理一次,确保消息的一致性和可靠性。

RabbitMQ

  1. 消息生产
    • 事务机制:生产者可以通过开启事务来确保消息的可靠发送。在事务模式下,生产者发送消息后调用tx.commit()方法提交事务,若提交成功则消息发送成功,若提交失败则可通过tx.rollback()回滚事务并重试发送消息。但事务机制会严重影响性能。
    • Confirm机制:RabbitMQ提供了Confirm机制,生产者将信道设置为Confirm模式后,发送的消息会被分配一个唯一的ID。当消息被Broker接收后,会发送一个确认消息给生产者,生产者通过监听确认消息来判断消息是否发送成功。若未收到确认消息,生产者可进行重试。
  2. 消息存储
    • 持久化机制:RabbitMQ支持消息、队列和交换器的持久化。将消息设置为持久化(deliveryMode = 2),队列和交换器声明时设置为持久化,这样在RabbitMQ服务器重启后,持久化的消息、队列和交换器依然存在,保证消息不会丢失。
    • 镜像队列:对于高可用性需求,可使用镜像队列。镜像队列会将主队列的数据同步到多个镜像队列,当主队列所在节点出现故障时,镜像队列中的一个会被提升为主队列,继续提供服务,确保消息的可靠性和一致性。
  3. 消息消费
    • 手动确认:消费者从队列获取消息后,默认是自动确认机制,即消费者一旦接收消息,RabbitMQ就认为该消息已被处理。为保证消息的可靠消费,可设置为手动确认模式。消费者处理完消息后,调用basic.ack方法向RabbitMQ发送确认消息,RabbitMQ才会将该消息从队列中删除。若消费者未确认或连接断开,RabbitMQ会将消息重新投递给其他消费者或重新放回队列。
    • 消费限流:通过设置basic.qos方法限制消费者每次接收的消息数量,避免消费者处理能力不足导致消息积压或丢失,保证消息消费的稳定性和可靠性。