mq - 消息队列的作用(面试)

队列(Queue)

队列是一种操作受限制的线性表,只允许在表的前端(front)进行删除操作,在表的后端(rear)进行插入操作。

开发人员最早接触的队列,应该是 LinkedList,LinkedList 除了是 List,也是一个 Queue(实际上还是一个stack)。

队列一般遵循先进先出的原则,但实际上这也不是绝对的,先后可以由其它权值判断,比如:要求长得高的人先消费(可以搜索词条 “优先队列”)。

消息队列(Message Queue)

消息队列(message queue),简称是 MQ,日常沟通可能直接称之为 Q。

虽然说,你把队列称之为消息队列,也挑不出啥毛病,不过日常交流中,消息队列一般指 rabbitmq、activemq 等技术成熟的产品。

Message Queue 与 Queue 相比,有很多非常复杂的改进:

  1. ACK 机制:如果无法消费、消费失败,不要取出队列中的消息;
  2. 断线恢复:客户端、服务端都有断线风险,需要保证重启后可恢复;
  3. 更加复杂的消息订阅模式,比如,生产端、消费端可以是多对多关联;

常见的应用场景

消息分发

对于一些大型项目,某些数据一旦产生,可能有无数个下游系统关注这些数据,主系统和子系统之间应当是完全解耦的,子系统需要有选择得进行注册、订阅。

案例:物联网中的采集仪,采集仪负责收集硬件数据,然后推送到业务系统,生成上一般通过消息队列实现这一功能。

应用解耦

和第一点的说法非常像,都属于 “消息订阅-发布” 的内容,不过是属于更小的应用,就比如微服务,详见 spring-boot-starter-amqp。

案例:A 同事开发一个模块,B 同事开发另一个模块,A 和 B 业务上发生耦合了,使用消息队列的情况下,双方只要协商好数据格式即可,一个人只要负责往队列发送数据,另一个人只要负责消费。

疑问:可能会有疑问,为什么不直接调用对方的代码?

回答:因为生产端、消费端可能都不止处理一种数据,如果互相调用会产生非常复杂的耦合,需要有一个中间层进行解耦。

流量消峰填谷

在短时间内,可能会产生大量的数据,服务器无法及时消化这些数据,这时候,先暂时缓存这些数据,等到服务器资源闲置时,再处理这些数据。

异步

严格上说,这并不算优点,优缺点并存,优点是如果无需关注数据是如何消费的,消息推送之后可以及时释放资源,而缺点,就是处理业务时,需要时刻关注状态的变化。

案例:以文件解压缩为例,A 线程发现文件,将文件信息推送到队列中,等待压缩,B 线程也发现这个文件,并且执行相同的操作,

这时候就容易出现问题,可能会把文件解压 2 次,文件从 “发现” 到 “解压成功” 的时间里,文件处于将要处理而未处理的特殊状态,“异步” 需要我们时时刻刻关注这种状态的变化。

posted on 2022-03-15 11:02  疯狂的妞妞  阅读(292)  评论(0)    收藏  举报

导航