2020---rabbitmq面试题

目录

 

一、使用rabbitmq优缺点

二、Kafka、ActiveMQ、RabbitMQ、RocketMQ 有什么优缺点?

三、介绍一下rabbitmq的几种工作模式

四、交换器类型有哪些

五、如何确保消息正确发送至RabbitMq

六、如何确保消息消费者消费了消息

七、如何避免消息重复投递或重复消费

八、如何解决丢数据的问题

九、死信队列和延迟队列的使用


一、使用rabbitmq优缺点

优点|

解耦:系统A在代码中直接调用系统B和系统C的代码,如果将D系统接入,系统A还需要修改代码,过于麻烦。

异步:将消息写入消息队列,非必要的业务逻辑以异步的方式进行运行,加快响应速度。

削峰:并发量大的时候,所有请求直接怼到数据库,造成数据库连接异常,可以采用延时队列的方式进行削峰。

缺点|

系统可用性降低,系统复杂度升高

二、Kafka、ActiveMQ、RabbitMQ、RocketMQ 有什么优缺点?

ActiveMq:没有经过大规模吞吐量场景的验证,社区也不是很活跃;

RabbitMq:基于erlang语言开发,研究源码很困难,但是确实人家是开源的,比较稳定的支持,活跃度也高;

RocketMq:RocketMQ是基于Java语言开发的,适合深入阅读源码,有需要可以站在源码层面解决线上生产问题,包括源码的二次开发和改造;

Kafka:Kafka的优势在于专为超高吞吐量的实时日志采集、实时数据同步、实时数据计算等场景来设计;

三、介绍一下rabbitmq的几种工作模式

(1)simple工作模式

生产者生产消息,将消息放到队列中,消费者消费消息(设置成手动的ack,但如果设置成手动ack,处理完后要及时发送ack消息给队列,否则会造成内存溢出)。

(2)work工作模式

消息生产者将消息放到队列中,消费者有多个同时监听同一个队列,消息消费者谁先拿到消息谁负责消费。隐患:高并发情况下,默认会产生某一个消息被多个消费者共同使用,可以设置一个开关(syncronize) 保证一条消息只能被一个消费者使用。

(3)发布订阅模式

每个消费者监听这自己的队列,生产者将消息发送到broker,由交换机将消息发送到各自绑定的队列中。

(4)路由模式

消息生产者按照routing key 发送消息到交换机,只有匹配上路由key对应的消息队列,对应的消费者才能消费消息

(5)主题模式

星号代表多个单词,井号代表一个单词;路由功能添加模糊匹配;

四、交换器类型有哪些

direct:如果路由键完全匹配,消息就被投递到相应的队列;

fanout:如果交换器收到消息,将会广播到所有绑定的队列上;

topic:可以使来自不同源头的消息能够到达同一个队列。 使用topic交换器时,可以使用通配符,比如:“*” 匹配特定位置的任意文本, “.” 把路由键分为了几部分,“#” 匹配所有规则等;

五、如何确保消息正确发送至RabbitMq

使用发送方确认模式,确保消息正确的发送到RabbitMq。发送方确认模式:将信道设置成confirm模式,则在信道上发布的消息都会被指派一个唯一Id。一旦消息正确写入到队列中或消息已被持久化,信道会发送一个确认给生产者(包含消息唯一Id);如果失败则,则发送一条nack信息。发送方确认模式是异步的,生产者在等待返回信息的同时,可以继续发送消息。

六、如何确保消息消费者消费了消息

接收方消息确认机制:消息接收每一条消息后都必须去确认。只有消费者确认了消息,RabbitMq才能安全的把消息从队列中删除;这里并没有用到超时机制,RabbitMQ仅通过Consumer的连接中断来确认是否需要重新发送消息。

(1)如果消费者接收到消息,在确认之前断开连接或取消订阅,RabbitMq会认为消息没有被分发,然后重新发送个给下一个订阅者。

(2)如果消费者接收到消息却没有确认消息,连接也为断开,则RabbitMq认为该消费者繁忙,不会给消费者分发更多的消息。

七、如何避免消息重复投递或重复消费

在消息生产时,Mq针对每个消息生成一个inner_msg_id,作为去重和幂等的依据,避免重复的消息进入队列;在消息消费时,必须要求消息体中必须有一个bizId(对于同一业务全局唯一,如支付ID、订单ID、帖子ID等)作为去重和幂等的依据,避免同一条消息被重复消费。

(1).比如,你拿到这个消息做数据库的insert操作。那就容易了,给这个消息做一个唯一主键,那么就算出现重复消费的情况,就会导致主键冲突,避免数据库出现脏数据。

(2)以redis为例,给消息分配一个全局id,只要消费过该消息,将<id,message>以K-V形式写入redis。那消费者开始消费前,先去redis中查询有没消费记录即可。

八、如何解决丢数据的问题

(1)生产者丢失数据:

1)发送方确认机制,将信道设置confirm模式,一旦信道进入confirm模式,所有信道上面的发布的消息都会被指派唯一的Id,且成功投递,rabbitMq会发送一个确认Basic.ACK(包含唯一的Id),丢失就发送nack。

2)事务机制:发送消息前,开启事物(channel.txSelect()),然后发送消息,如果发送过程中出现什么异常,事物就会回滚(channel.txRollback()),如果发送成功则提交事物(channel.txCommit())。

(2)消息队列丢失数据:开启持久化磁盘配置+confirm机制配合使用

可以在消息持久化到磁盘后,再给生产者发送一个ACK信号,如果消息持久化磁盘之前,rabbitmq阵亡那么生产者收不到ACK信号,生产者会自动重发。

设置:将queue持久化标识durable=true/发送消息将deliveryMode=2/消息还没持久化到磁盘时,可能服务已经死掉了,引入mirrored-queue镜像队列

(3)消费者丢失数据

手动确认模式:如果消费者来不及处理就死掉时,没有响应ack时会重复发送一条信息给其他消费者进行消费;如果监听程序处理异常了,且未对异常进行捕获,会一直重复接收消息,然后一直抛异常;如果对异常进行了捕获,但是没有在finally里ack,也会一直重复发送消息(重试机制);每次你确定处理完一条消息,在发送ack消息给rabbitmq。

九、死信队列和延迟队列的使用

死信队列产生的条件:(1)消息被拒绝,并且required=false;(2)消息ttl过期;(3)队列达到最大长度

解决办法:通过死信队列,将负责监听死信的应用程序进行处理,将产生死信通过程序的配置路由到指定的死信队列,然后监听死信队列,将接收到的死信做后续处理。

延时队列:消费者监听死信交换器绑定的队列,而不要监听消息发送的队列。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值