1、RabbitMQ 如何保证消息不丢失RabbitMQ 消息可靠性需要三个环节共同保障生产端通过生产者确认确认消息被 Broker 接收配合 mandatory 回调处理路由失败防止消息发到 Exchange 后没进队列。存储端消息持久化队列持久化。并使用复制型队列例如仲裁队列或Streams保证 Broker 重启数据不丢。消费端手动 Ack处理成功后才确认失败消息进入死信队列业务层做幂等防止重复消费。2、什么是死信队列如何导致的当消息在一个队列中变成死信dead message之后它能被重新发送到另一个交换器中这个交换器就是死信交换器跟它绑定的队列就称之为死信队列。导致死信的常见原因消息被拒并且关闭重入队列、消息 TTL 过期。队列达到长度限制消息被丢弃。Quorum Queue 中消息返回次数超过阈值。3、RabbitMQ 有哪些交换机类型Direct Exchange直连交换机核心逻辑是路由键Routing Key与绑定键Binding Key完全一致时消息才会被路由到对应队列。适合需要精准路由的场景。Fanout Exchange扇出交换机核心逻辑是忽略路由键将消息路由到所有与该交换机绑定的队列。适合需要广播消息的场景。Topic Exchange主题交换机核心逻辑是通过通配符匹配路由键与绑定键支持按“主题”批量路由消息。适合需要分类批量路由的场景。Headers Exchange头部交换机核心逻辑是生产者发送消息时设置消息头交换机根据绑定队列时的头部规则路由消息。实际使用较少。4、什么是延迟队列怎么实现延迟队列保存的是延迟消息消息已经发送到 RabbitMQ但业务希望它过一段时间后再被消费者拿到。RabbitMQ 本身没有延迟队列要实现延迟消息一般有两种方式使用 TTL 死信交换器。消息先进入带 TTL 的队列过期后被投递到死信交换器再进入消费队列。使用插件提供的交换器可以按消息设置延迟时间。可以实现秒、分钟、小时级延迟最多一两天扩展什么是队列头部阻塞当你为每条消息设置不同的 TTL并将它们发送到同一个队列时。RabbitMQ 的过期消息判定机制是顺序的它只会检查队列头部的消息是否过期。队列头部消息的过期时间决定了整个队列的“阻塞”状态。例如A在队头10秒过期B在队中1秒过期那么它会一直等A过期感知不到B过期了。TTL死信交换机有什么缺点缺点是如果为每个消息设置不同TTL它容易受到队列头部阻塞影响而如果每种延迟时间都建一组队列维护成本较高。如果要做天、周、月级调度或者要堆积十万、百万级延迟消息如何处理应使用外部存储和调度系统。5、RabbitMQ 的高可用怎么保证分两层集群和队列复制。集群只负责管理元数据和连接队列里的消息是否复制要看队列类型。RabbitMQ 4.x 中Classic Queue不复制消息单节点存储。镜像队列已在 4.0 移除是旧版本方案基于主从复制主节点宕机后需要选举过程中可能丢消息。仲裁队列基于 Raft 协议消息复制到多个节点写入需要多数节点确认适合订单、支付等不能丢消息的场景。Streams也是复制型更适合日志回放和大量堆积场景。6、怎么保证消息不乱序原因生产者把顺序相关的消息发到同一个队列但消费者是多线程并发消费处理速度不同导致顺序错乱。解决方案强制串行只启动一个消费者单线程消费消息按入队顺序逐个处理。吞吐量低。分区顺序使用它内置插件根据请求的特征如用户ID计算哈希值让相同特征消息进入同一队列。队列绑定的每个消费者内部存ID做分组排队让相同ID的消息串行处理不同ID的并行。业务层排序每条消息带一个序号消费者收到后先检查序号如果序号等于当前序号则处理小于则丢弃大于则等待直到按顺序补齐。7、怎么保证消息不重复原因消费者因为处理超时或者网络中断等导致没有发ACK确认导致RabbitMQ认为消费失败重新投递消息。解决方案数据库唯一约束比如订单消息用消息id作为唯一键插入消息表处理前检查消息id是否存在。业务状态机比如订单状态从1→2更新时加条件update...set status2 where status1。Redis分布式锁消费前用SETNX加锁加锁成功才设置redis标记位并处理业务过期时间设长一些。重复消息来时如果标记存在就不处理。