MQ面试题
一.消息积压问题
1.产生原因:
生产者生产消息的速度 远高于 消费者消费消息的速度?于是就会造成消息积压在MQ
2.缓解消息积压问题
当消息队列因积压问题导致压力过大,这种情况下,我们可以采用惰性队列先将生产的消息存入磁盘,在消费时再加载到内存。以此来缓解队列存储消息的压力,但这并不能解决积压问题。
3.分析为什么会产生消息积压
1.设计是否有问题?
如果是,重新设置生产者与消费者数量匹配
例如:生产者每秒生产100条消息,消费者每秒消费10消息
为了消息不积压一个生产者配10个消费者
2.消费者出了问题?
消费者宕机了,第一步先修复消费者宕机情况
第二步:临时开多个消费者消费积压的消息,等到消息消费的差不多的情况时关闭临时的消费者
二.MQ如何保证消息的可靠性?如何保证消息不丢失
1、什么是消息的可靠性
消息由生产者发送到MQ,最终被消费者正常消费完成。这就叫消息可靠
2、消息丢失的几种情况?
1、生产者连不上MQ
因为网络不可靠,导致生产者暂时连不上MQ
此时生产者开启重试策略
spring: rabbitmq:
connection-timeout: 1s # 设置MQ的连接超时时间
template:
retry:
enabled: true # 开启超时重试机制
initial-interval: 1000ms # 失败后的初始等待时间
multiplier: 1 # 失败后下次的等待时长倍数,下次等待时长 = 上次等待时长 * multiplier
max-attempts: 3 # 总共尝试次数
2、生产者发送消息未到达交换机
开启 confirm 回调机制。每个生产者独立配置
到达交换机,返回ack
没到交换机,返回nack
3、消息到达交换机,没有正确路由到队列
开启 return 回调机制,RabbitMQ只有一个
没到队列,失败,会被回调
4、MQ宕机,队列中的消息不见了
5、消费者收到消息,还没消费,消费者宕机
开启自动ack,并且设置本地重试策略,当本地重试次数耗尽后,失败消息路由到错误队列。
3、如何解决
1、生产者:
开启重试策略,保证消息正确到达MQ,如果重试次数耗尽,则写入数据库,后期交由人工处理
开启confirm机制,保证消息正确到达交换机
开启return机制,保证消息正确到达队列
2、持久化操作
创建交换机、队列、消息时设置持久化(默认就是持久化),保证MQ宕机后重启不丢失
3、消费者
开启自动ack,并且设置本地重试策略,当本地重试次数耗尽后,失败消息路由到错误队列。
监听错误队列,把消息写入数据库,后期交由人工处理
三.消息重复消费问题
非幂等性操作
1、数据库唯一约束
2、方案一:使用Redis来实现
生产者发送消息时,设置消息ID
消费者先从Redis中获取消息ID,如果存在,则表示有人在消费消息,我什么都不做。如果不存在,表示是该消息是第一次被消费,正常消费,并且向存储Key为消息ID的数据到Redis,同时设置过期时间
3、业务判断:由一个状态到另一个状态,必须加条件是初始状态。
4、MQ可靠性保证并不是100%,所以有可能消费者没有收到MQ的消息,那么后续就无法执行了。我们可以主动发起查询去获取最新结果,然后继续完成后面的业务操作
四.死信交换机
1、成为死信的几种情况
1.1、消费者使用basic.reject 或 basic.nack 声明消费失败,并且消息的requeue参数设置为false
1.2、消息设置了过期时间,或者消息存放的队列设置了过期时间,超时无人消费
1.3、要投递的队列消息满了,无法投递
这些就是死信,然后会通过路由规则经过交换机路由到一个队列,这个交换机就叫死信交换机,这个队列就是死信队列
五.与Kafka的区别
1、Kafka
1、优点
吞吐量大,功能强大:处理流媒体
2、缺点
时效性差:消息延迟时间比MQ长
3、特点
重Topic:收发消息都必须指定Topic
拉模式:由消费者主动去Broker中拉取消息
消息消费完后,不会删除,保留历史消息
2、RabbitMQ
1、优点
时效性强、可靠性高
2、缺点
吞吐量比Kafka小
3、特点
轻Topic:不同工作模式可以选择是否使用Topic
推模式:由Broker主动把消息推送给消费者
消息阅后即焚
六.消息消费如何保证顺序消息
1、消费者指定线程消费数为1
2、MQ增加队列属性为 x-single-active-consumer 为true

浙公网安备 33010602011771号