一.题目介绍
1.题目来源
实际面试中遇到,形式的话有书面解答也有口述
2.题目
1)消息队列是什么?
2)你了解的消息队列有哪些?
3)消息队列在实际的开发中使用消息队列处理哪些业务,你使用消息队列遇到了哪些问题并且是如何解决的?
4)说说消息队列的实现原理
二.具体解答
1.消息队列是什么
消息队列就是一个使用队列来通信的组件。
这话有点笼统和拗口,简单来说消息队列就是在服务与服务之间传递消息的中转站,消息的发起方叫生产者,消息的接收方叫消费者,而我们可以利用这个中转站对其中的消息进行一系列的处理,在实际的业务场景中消息队列一般是起到系统解耦,流量削峰以及延时推送,
2.消息队列有哪些
这个就直接上图了,图文比较清楚,还有性能上的对比
3.消息队列的运用
1)系统解耦
在实际的开发中,一个系统与另外一个系统之间的通信,一般是采用RPC也就是接口调用的方式(Dubbo),还有一种就是Http形式的调用, Spring Cloud Feign本质上也是基于Http形式的接口调用,那如果这个是应该微服务体系的架构,并且项目是前置项目那就需要去调用很多的接口,这样就容易出现一个情况,在注册中心挂掉以后,接口不可用的情况下,业务数据是没法从前置系统到达后面处理业务的各个系统的,就会出现数据丢失的情况,如果还是高峰并发期很可能影响到整个系统的正常运行,那可以怎么办呢?消息队列可以解决这个问题,使用消息队列后系统与系统之间传递的是消息而不用互相调用接口,实现系统解耦,另外就是可以避免一些老系统与新系统之间的版本问题。
2)流量削峰
先想这么一个问题,现在你手里的是一个电商项目,正在做活动,瞬时流量上千万,除了多线程和并发处理,你还能怎么优化这个系统?这种瞬时流量'冲击'过来的时候可能会使得这个微服务体系崩溃掉,有人说限流,限流确实能起到一部分作用,就像秒杀手机一样,让先进来的这部分让先购买,后面进来的排队,但是客户是没有耐心的,可能看着要排队就直接退出了,那针对这种场景,消息队列可以怎么去做?消息队列可以缓解前置系统传到后面系统的数据压力,把这种订单信息放消息队列里,后面的系统接收到消息以后陆续处理,可以很大程度上的缓解系统压力。
3)延时推送&消息必达
这是个老生常谈的问题了,需要实现短消息推送和订单超时取消时就可以使用消息队列去做,而所谓的消息必达指的是消息队列的ACK机制,但是消息真的就是必达吗?还有消息会丢失这种情况会发生。
4)问题及解决方案
消息丢失:ACK机制和死信队列
消息重复:目前MQ没法保证消息不重复,期待后续的更新,业务场景里可以使用幂等去保证消息不重复,比如不会同一个订单发送两条通知消息
处理消息堆积:有时候消息可能产生堆积,那就得需要定时查看控制台并及时处理
4.消息队列的实现原理
从生产者和消费者的角度:
生产者发送消息
1.生产者连接到 RabbitMQ Broker,建立一个连接(Connection),开启一个信道(Channel)
2.生产者声明一个交换器,并设置相关属性,比如交换机类型、是否持久化等
3.生产者声明一个队列并设置相关属性,比如是否排他、是否持久化、是否自动删除等
4.生产者通过路由键将交换器和队列绑定起来
5.生产者发送消息至 RabbitMQ Broker,其中包含路由键、交换器等信息
6.相应的交换器根据收到的路由键查找相匹配的队列
7.如果找到,则将从生产者发送过来的消息存入相应的队列中
8.如果没有找到,则根据生产者配置的属性选择丢弃还是回退给生产者
9.关闭信道
10.关闭连接
消费者接收消息的过程
1.消费者连接到 RabbitMQ Broker,建立一个连接(Connection),开启一个信道(Channel)
2.消费者向 RabbitMQ Broker 请求消费相应队列中的消息,可能会设置相应的回调函数,以及做一些准备工作
3.等待 RabbitMQ Broker 回应并投递相应队列中的消息,消费者接收消息
4.消费者确认(ack)接收到的消息
5.RabbitMQ 从队列中删除相应已经被确认的消息
6.关闭信道
7.关闭连接
三.题后思考
MQ的题目在面试和笔试中很常见,所以得用心去准备一下,挑关键点进行解答即可,就在考察实现原理这块时,也不可能说百分之百的记住每一个步骤,大体的流程知道就可以了。