RabbitMQ相关面试题

发送与接收消息的流程

  • 生产者发送消息的流程
    (1)生产者连接RabbitMQ,建立TCP连接( Connection),开启信道(Channel)
    (2)生产者声明一个Exchange(交换器),并设置相关属性,比如交换器类型、是否持久化等
    (3)生产者声明一个队列井设置相关属性,比如是否排他、是否持久化、是否自动删除等
    (4)生产者通过bindingKey (绑定Key)将交换器和队列绑定( binding )起来
    (5)生产者发送消息至RabbitMQ Broker,其中包含routingKey (路由键)、交换器等信息
    (6)相应的交换器根据接收到的routingKey 查找相匹配的队列。
    (7)如果找到,则将从生产者发送过来的消息存入相应的队列中。
    (8)如果没有找到,则根据生产者配置的属性选择丢弃还是回退给生产者
    (9)关闭信道。
    (10)关闭连接。
  • 消费者接收消息的过程
    (1)消费者连接到RabbitMQ Broker ,建立一个连接(Connection ) ,开启一个信道(Channel) 。
    (2)消费者向RabbitMQ Broker 请求消费相应队列中的消息,可能会设置相应的回调函数, 以及做一些准备工作
    (3)等待RabbitMQ Broker 回应并投递相应队列中的消息, 消费者接收消息。
    (4)消费者确认( ack) 接收到的消息。
    (5)RabbitMQ 从队列中删除相应己经被确认的消息。
    (6)关闭信道。
    (7)关闭连接。

几种模式

  1. simple简单模式;
    一个生产者,一个队列,一个消费者
    一个生产者,一个队列,一个消费者,不需要经过交换机

  2. work工作模式(资源的竞争,轮循);
    在这里插入图片描述
    一个生产者,一个队列,多个消费者

  3. publish/subscribe发布订阅(共享资源);
    在这里插入图片描述
    生产者将消息发送到交换机,交换机发送给每一个队列,每个队列下面可以有多个消费者,都是相同的消息,Routing Key为空

  4. routing路由模式;
    在这里插入图片描述
    交换机根据Routing Key的名字将消息发送给指定的队列

  5. topic 主题模式。
    在这里插入图片描述
    主题模式是在原有的 Routing Key 增加了通配符,可以进行 Routing Key 的模糊匹配,进行更加灵活的消息分发。
    *和#,分表是主题模式的通配符,*代表单个关键字,#代表多个关键字。
    在实际使用场景中, 路由模式的效率是高于主题模式,实际工作中可以使用路由模式解决的问题就尽量不要采用主题模式。

Mq消息积压怎么处理

  • 产生原因有可能是

    • 消费端宕机
    • 消费端消费能力不足
    • 生产端发送流量过大
  • 方案一:通常的解决方案就是增加消费端实例。说白了就是增加机器。如果出现线上事故,能申请多少机器就申请多少机器,争取在最短的时间内消费掉积压在MQ中的消息。

  • 方案二:如果申请机器行不通,毕竟公司的机器是有限的,此时可以增加消费端的消费能力。在MQ的配置中配置"最大消费者数量"与"每次从队列中获取的消息数量"

  • 方案三:如果还是不能解决问题的话,还有另外一种解决方案。紧急上线专门用于记录消息的队列,不多BB,先把MQ中的消息记录到数据库中,然后再慢慢的消化处理。

死信队列是什么

  • producer 将消息投递到 broker 或者直接到 queue 里了,consumer 从 queue 取出消息进行消费,但某些时候由于特定的原因导致 queue 中的某些消息无法被消费,这样的消息如果没有后续的处理,就变成了死信,有死信自然就有了死信队列。
  • 死信来源
    1、消息 TTL 过期
    2、队列达到最大长度(队列满了,无法再添加数据到 mq 中)
    3、消息被拒绝(basic.reject 或 basic.nack)并且 requeue=false.

如何实现延时队列

ttl+死信

MQ如何保证消息的可靠性

  • 生产者端
    1、事务机制
    AMQP协议提供了事务机制,在投递消息时开启事务支持,如果消息投递失败,则回滚事务。
    2、confirm

  • 消费者端

yml中配置acknowledge-mode: manual手动签收

public void receive(String message, @Headers Map<String,Object> headers, Channel channel) throws Exception{

    System.out.println(message);
    // 唯一的消息ID
    Long deliverTag = (Long) headers.get(AmqpHeaders.DELIVERY_TAG);
    // 确认该条消息
    if(...){
        channel.basicAck(deliverTag,false);
    }else{
        // 消费失败,消息重返队列
        channel.basicNack(deliverTag,false,true);
    }

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值