消息队列相关面试

2024-01-28 八股文

# RabbitMQ

1.RabbitMQ如何实现延时队列?

利用私信队列或延时队列插件,消息队列中的消息可以设置存活时间,存活时间到则进入私信队列(本质也是交换机),我们监听这个私信队列的消息即可。

2.RabbitMQ 是如何保证高可用的?
  • 普通集群模式:消费者/生产者连接的机器如果没有队列实例,则会被转发到有响应实例的机器,如果某台宕机不会影响所有业务。
  • 镜像模式:所有RabbitMQ内容相同,一个节点宕机不会影响其他节点。
3.RabbitMQ如何防止重复消费?

RabbitMQ有消息确认机制,如果因为网络延迟等,则需要自行进行幂等处理,使用'一锁、二判(根据id等的状态进行判断)、三更新'。

4.RabbitMQ如何保证消息不丢?

无法100%保证,但是可以尽量减少丢失,将队列和交换机进行持久化,以及设置消息持久化。

5.如何保障消息一定能发送到RabbitMQ?

两个地方可能丢失消息,生产者发送到交换机,以及交换机发送到队列;解决方式是分别注册两个监听,用来处理如果发送失败的处理。

// 启用Publisher Confirms
channel.confirmSelect();

// 设置Publisher Confirms回调
channel.addConfirmListener(new ConfirmListener() {
    @Override
    public void handleAck(long deliveryTag, boolean multiple) throws IOException {
        System.out.println("Message confirmed with deliveryTag: " + deliveryTag);
        // 在这里处理消息确认
    }

    @Override
    public void handleNack(long deliveryTag, boolean multiple) throws IOException {
        System.out.println("Message not confirmed with deliveryTag: " + deliveryTag);
        // 在这里处理消息未确认
    }
});
// 启用Publisher Returns
channel.addReturnListener(new ReturnListener() {
    @Override
    public void handleReturn(int replyCode, String replyText, String exchange, String routingKey, AMQP.BasicProperties properties, byte[] body) throws IOException {
        System.out.println("Message returned with replyCode: " + replyCode);
        // 在这里处理消息发送到Queue失败的返回
    }
});
6.RabbitMQ如何实现消费端限流

消费者端指定最大的未确认消息数,当达到这个限制时,RabbitMQ将不再推送新的消息给消费者,直到有一些消息得到确认。

# RocketMQ

1.RocketMQ如何保证消息的顺序性?

发送到同一个队列,消费也是在同一个队列中。消费者有两种,有序消费模式和并发消费模式,采用有序消费模式保证只有一个消费者进行消费,即可保证消息的顺序性。

2.RocketMQ如何保证消息不丢失?
  1. 将消息保存机制修改为同步刷盘:消息发送分为同步和异步两种,同步方式是当消息存储在内存时就返回成功,如果此时机器挂了,消息丢失。
  2. 异步复制改为同步复制:RocketMQ采用集群部署,通常是一主多从(不使用集群很难保证不丢失),当主节点收到消息就会返回成功,改成同步复制则确保所有节点复制完毕才保证成功。
  3. 如果是异步方式则需要重写相关方法,Broker处理后会回调这些方法(成功失败都会回调)
3.RocketMQ如何实现延时消息?
  • RocketMQ本身支持延时消息和定时消息,传递时间戳,24小时内为延时消息,超过24小时识别为定时消息。
  • 延时消息必须topic为Delay类型
4.RocketMQ消息堆积了怎么解决?
  1. 增加消费者数量
  2. 提示消费速度,如数据库写入操作等使用异步写入
  3. 增加Topic队列数
  4. 降低生产者发送速度也可以
5.消息队列使用拉模式好还是推模式好?
  • 推:建立长连接,broker主动推送数据到消费者,好处是消息是实时的,但可能造成消息堆积,适合实时性要求高的场景。
  • 拉:消费者到broker拉取消息,消费者自己控制拉取速度,可根据自身消费能力动态拉取。

# kafka相关

1.Kafka如何保证消息不丢失?
  • 首先,Kafka只对已提交的消息做最大限度的持久化保证不丢失,但是没办法保证100%。
  • Producer可以设置重试次数,或通过回调来处理重复发送
2.聊一聊Kafka中Producer发送消息的acks机制?
  • acks=0: 请求立即返回,不等待Leader确认,最高吞吐率,消息发送成功不保证。
  • acks=-1: 分区Leader必须等待消息成功写入所有ISR副本,提供最高持久性保证,吞吐率最低。
  • acks=1: Leader副本应答并写入消息到本地日志,Producer请求成功,但挂掉后消息可能丢失,提供不错持久性保证和吞吐率。