# 消息队列面试总结
# 消息队列有哪些作用?
- 异步解耦
消息队列与企业级网关的功能相似,都可以对两个系统进行解耦,区别是企业级网关的解耦是一种同步行为。消息队列的解耦则是一种异步行为。 - 削峰填谷 针对两个能力不对称的系统之间的交互,可以使用消息队列进行削峰填谷。
# 什么是死信队列?
死信队列指的是消息消费方无法处理的消息,目前主流的三个消息队列产品中,RabbitMQ和RocketMQ提供了死信队列功能,Kakfa则未提供该能力。
# 消息在什么情况下会进入死信队列?
- 队列容量已满
当消息队列中消息长期未被消费,导致消息队列容量已满的情况下,队列前面的消息会被丢入死信队列中。 - 消息过期未被消费
消息可以设置过期时间,如果过期时间到了还没被消费,同样会进入死信队列。 - 消费方明确拒绝消息投递
消费方收到消息后,可以对消息进行处理,如果消费方识别到该消息无法处理(如特殊异常),则消费方可以返回消费失败且明确拒绝重新投递的信号。不同的消息队列产品对该信号有不同的处理方式,RabbitMQ会立刻将该消息丢入死信队列。RocketMQ则会再次重试(重试依然可能重新投递给刚才拒绝的消费者),直到投递16次均失败,才会将消息丢入死信队列。
# 什么是延时队列?
字面意思,就是消息队列收到消息之后不会立刻投递,而是在满足投递要求(如设置的延时是3小时后/凌晨0点)的时候才会投递消息。三款主流的MQ产品中,仅RocketMQ直接支持延时队列,RabbitMQ和Kafka都需要使用插件支持。
# 消息队列如何保证消息可靠传输?
消息可靠传输代表了两层意思,即消息既不能多,也不能少(这部分有点类似TCP的三次握手,四次挥手,都是需要ACK机制)。
1.为了保证消息不多,即生产者不能重复生产消息,消费者也不能重复消费消息。(生产者重复生产消息不常出现,也无法避免,只能通过消费者做幂等性控制,保证重复消费也不会出问题。)
2.为了保证消息不少,生产者发送消息时,需要确认broker收到了消息(kafka的ack机制)
3.为了确保消息不少,broker要等消费者真正消费到了消息后才删除消息(消费端ack机制)