消息队列常见面试题

1.为什么要用消息队列

解耦、异步、削峰

  • A系统调用B系统、C系统,传统的调用是直接调用,但是当B系统说我不需要你提供数据了,这时候A需要改代码,C系统说我不需要某个字段了,这时候A也要改代码,如果又多了一个D系统,A又要写代码。为了实现解耦,引入消息队列,A将产生的数据丢到消息队列中,哪个系统需要 哪个系统就去取;
  • A系统调用B系统,B系统由于某个需要调用第三方接口超时,导致A系统响应速度慢,而B系统的好坏又不会影响业务逻辑,所以可以改为A异步调用B,A将消息丢到消息队列中,B系统订阅消息,实现A的快速响应;
  • 当大量流量请求到系统A时,由于数据库的处理能力有限,造成数据库连接异常。使用消息队列,大量请求先丢到消息队列中,系统A使用按批拉数据的方式,批量处理数据,生产中,高峰期短暂的消息积压是允许的。
2.使用消息队列有什么缺点
  • 系统复杂性增加:加了消息队列,需要保证消息不会重复消费,需要保证消息的可靠性,需要保证消息队列的高可用
  • 系统的可用性降低:如果消息队列挂了,那么系统也会受到影响
3.为什么选用RocketMQ;RocketMQ和ActiveMQ的区别

RocketMQ模型简单、接口易用,在阿里大规模使用,社区活跃,单机吞吐量10万级,可用性非常高,消息理论上不会丢失;

  • ActiveMQ严格遵循JMS规范,可持久化到内存、文件、数据库,可用性高主要是主从,多语言支持,消失丢失率低;
  • RocketMQ持久化到磁盘文件,可用性非常高,支持分布式,只支持Java,消息理论上不会丢失;

4.RocketMQ是怎么保证系统高可用的?

  • 多Master部署,防止单点故障;
  • 主从结构,消息冗余,防止消息丢失;
5.MQ能否保证消息必达,即消息的可靠性?

为了降低消息丢失的概率,MQ需要进行超时和重传

(1) MQ-client-sender 发送消息给MQ-server

(2) MQ-server接收到消息后,发送 ACK消息给发送方

(3) MQ-client-sender 接收到 ACK消息后,则 消息已经投递成功

如果上述 2 消息丢失或者超时,MQ-client-sender 内的 timer 会重发消息,直到收到 ACK消息,如果重试N次后还未收到,则回调发送失败。需要注意的是,这个过程中 MQ-server 可能会收到同一条消息的多次重发。

对每条消息,MQ系统内部必须生成一个inner-msg-id,作为去重和幂等的依据,这个内部消息ID的特性是:

  • 全局唯一
  • MQ生成,具备业务无关性,对消息发送方和消息接收方屏蔽

(4) MQ-server 将消息发送给 MQ-client-receiver

(5) MQ-client-receiver 得到消息处理业务逻辑

(6) MQ-client-receiver 回复 ACK消息给 MQ-server

(7) MQ-server收到 ACK消息,将已消费的消息删除

如果上述 6 消息丢失或者超时,MQ-server 内的 timer 会重发消息,直到 MQ-server 收到ACK消息 并且 将已消费的消息删除,这个过程也可能会重发多次,MQ-client-receiver 也可能会收到同一条消息的多次重发。

需要强调的是,MQ-client-receiver 回ACK给 MQ-server,是消息消费业务方的主动调用行为,不能由 MQ-client-sender 自动发起,因为MQ系统不知道消费方什么时候真正消费成功。

为了保证业务幂等性,业务消息体中,必须有一个biz-id,作为去重和幂等的依据,这个业务ID的特性是:

  • 对于同一个业务场景,全局唯一
  • 由业务消息发送方生成,业务相关,对MQ透明
  • 由业务消息消费方负责判重,以保证幂等

最常见的业务ID有:支付ID,订单ID,帖子ID等。

欢迎关注我的公众号~ 搜索公众号: 码咖 或者 扫描下方二维码:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值