mq - 消息队列的作用(面试)
队列(Queue)
队列是一种操作受限制的线性表,只允许在表的前端(front)进行删除操作,在表的后端(rear)进行插入操作。
开发人员最早接触的队列,应该是 LinkedList,LinkedList 除了是 List,也是一个 Queue(实际上还是一个stack)。
队列一般遵循先进先出的原则,但实际上这也不是绝对的,先后可以由其它权值判断,比如:要求长得高的人先消费(可以搜索词条 “优先队列”)。
消息队列(Message Queue)
消息队列(message queue),简称是 MQ,日常沟通可能直接称之为 Q。
虽然说,你把队列称之为消息队列,也挑不出啥毛病,不过日常交流中,消息队列一般指 rabbitmq、activemq 等技术成熟的产品。
Message Queue 与 Queue 相比,有很多非常复杂的改进:
- ACK 机制:如果无法消费、消费失败,不要取出队列中的消息;
- 断线恢复:客户端、服务端都有断线风险,需要保证重启后可恢复;
- 更加复杂的消息订阅模式,比如,生产端、消费端可以是多对多关联;
常见的应用场景
消息分发
对于一些大型项目,某些数据一旦产生,可能有无数个下游系统关注这些数据,主系统和子系统之间应当是完全解耦的,子系统需要有选择得进行注册、订阅。
案例:物联网中的采集仪,采集仪负责收集硬件数据,然后推送到业务系统,生成上一般通过消息队列实现这一功能。
应用解耦
和第一点的说法非常像,都属于 “消息订阅-发布” 的内容,不过是属于更小的应用,就比如微服务,详见 spring-boot-starter-amqp。
案例:A 同事开发一个模块,B 同事开发另一个模块,A 和 B 业务上发生耦合了,使用消息队列的情况下,双方只要协商好数据格式即可,一个人只要负责往队列发送数据,另一个人只要负责消费。
疑问:可能会有疑问,为什么不直接调用对方的代码?
回答:因为生产端、消费端可能都不止处理一种数据,如果互相调用会产生非常复杂的耦合,需要有一个中间层进行解耦。
流量消峰填谷
在短时间内,可能会产生大量的数据,服务器无法及时消化这些数据,这时候,先暂时缓存这些数据,等到服务器资源闲置时,再处理这些数据。
异步
严格上说,这并不算优点,优缺点并存,优点是如果无需关注数据是如何消费的,消息推送之后可以及时释放资源,而缺点,就是处理业务时,需要时刻关注状态的变化。
案例:以文件解压缩为例,A 线程发现文件,将文件信息推送到队列中,等待压缩,B 线程也发现这个文件,并且执行相同的操作,
这时候就容易出现问题,可能会把文件解压 2 次,文件从 “发现” 到 “解压成功” 的时间里,文件处于将要处理而未处理的特殊状态,“异步” 需要我们时时刻刻关注这种状态的变化。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY