消息队列是大型高并发架构的核心,也是大厂重点考察的对象,下面我就全面来详解消息队列@mikechen
消息队列
消息队列 ,全称是:“Message Queue”,很多时候我们也简称为:“ MQ”,本质就是一个保存消息的队列。
如下图所示:
允许不同的应用程序通过发送、和接收消息进行数据交换,从而实现系统解耦、提高系统可扩展性、和性能。
主要解决以下几点问题:
1.异步通信
异步通信是指:系统中的组件通过消息队列,进行异步消息传递,发送者不需要等待接收者处理完毕,即可继续执行其他任务。
比如:邮件服务异步发送邮件给用户,注册服务立即返回响应给用户,而不必等待邮件发送完成,这就是典型的”异步通信“。
2.解耦
消息队列使生产者,和消费者之间解耦,生产者只需将消息发送到消息队列中,而不需要知道消息的最终处理者是谁。
这种解耦使得系统组件之间的依赖关系减少,提高了系统的灵活性、和可维护性。
3.可靠性
消息队列可以保证消息的可靠传输,比如:可以通过持久化、和确认机制,确保消息不丢失。
4.流量削峰
消息队列可以缓解突发流量对系统的压力,比如:在抢购活动中,订单请求量在短时间内激增。
消息队列:可以暂存这些订单请求,后台服务按能力逐步处理,防止系统瘫痪,这就是典型的”流量削峰“。
总之,消息队列可以用于:解耦、异步处理、削峰填谷、和可靠传输…等场景,使得它在现代分布式系统、和微服务架构中成为关键组件。
消息队列实现原理
消息队列的实现,如下图所示:
MQ的整体架构通常包括以下几个组件:
生产者(Producer):
生产者:是负责生成、和发送消息到消息队列的应用程序、或组件。
生产者可以是任何生成数据的系统部分,比如:用户操作触发的事件、定时任务、数据采集系统。。。等。
还是举一个例子:在电子商务系统中,订单服务在用户提交订单后生成订单消息,并将其发送到订单处理队列中,这就是生产者。
消息代理(Broker):
生产者将生成的消息,发送到消息代理(Broker),并指定消息应存储的队列、或主题。
这里的代理(Broker):就是负责消息接收、存储、和分发消息的中间件。
- 接收消息:从生产者接收消息,并确认接收成功;
- 存储消息:将消息存储在内存、或持久化存储中,根据配置、和需求选择存储策略;
- 分发消息:根据消费者的订阅、和队列的配置,将消息传递给相应的消费者;
- 路由和负载均衡:决定消息的分发路径,确保系统负载均衡、和高效运行。
消息队列(Queue):
queue就是:存储消息的容器,按照一定顺序传递消息。
消费者(Consumer):
这个没什么可说的,就是消费者:从消息队列读取并处理消息的应用程序、或组件。
消息体(Message):
消息的内容,包括消息头(metadata)和消息体(payload)。
- 消息头(Metadata):包含消息的元数据,如消息ID、时间戳、优先级、路由信息…等。
- 消息体(Payload):实际传递的数据内容,可以是文本、二进制数据、JSON、XML……等格式。
消息幂等性
除了考虑上面的设计外,还需要考到如何避免重复处理。
比如:如何确保消费者处理消息时具备幂等性,即同一消息多次处理不会造成副作用。
可以通过消息ID、状态记录等手段实现幂等性。
去重策略
对于可能重复的消息,设计去重策略,确保同一消息只被处理一次。
消息队列类型
消息队列主要包含两种,一个是”点对点“,一个是”发布订阅模型“。
1.点对点
在点对点模型中,消息在队列中存储,只有一个消费者可以消费该消息,一旦消息被消费,它就会从队列中移除。
应用场景:
- 订单处理系统:订单服务将订单消息放入队列,每个订单消息只需要被一个处理服务消费和处理。
2.发布/订阅
在发布订阅模型中,消息发布者将消息发送到主题(Topic),所有订阅该主题的消费者都可以接收到消息。
如下图所示:
每条消息可以被多个消费者消费,消息不会因为被某个消费者读取而删除。
发布订阅模型包含三个角色:
- 发布者(Publisher):生成并发送消息到主题的应用程序、或组件;
- 主题(Topic):存储消息的容器,允许多个消费者订阅;
- 订阅者(Subscriber):订阅主题并接收消息的应用程序、或组件。
应用场景:
- 日志收集系统:日志生成者将日志消息发布到主题,多个日志处理器(如:分析系统、监控系统)订阅该主题,接收日志消息进行处理。
3.点对点模式和发布订阅模式的区别
主要体现在如下3点:
1、消息接收者的区别
点对点:每条消息只被一个消费者接收和处理。
发布订阅:每条消息可以被,多个订阅者接收、和处理。
2、消息存储方式的区别
点对点:消息存储在队列中,消费者读取后消息从队列中删除。
发布订阅:消息存储在主题中,所有订阅者接收完消息后消息才会删除。
3、适用场景的区别
点对点:适用于需要保证消息只处理一次的场景,如:任务处理、订单处理。
发布订阅:适用于需要广播消息的场景,如:日志收集、事件通知。
常用的消息队列?
以下是一些常用的消息队列系统:
1.RabbitMQ
RabbitMQ是基于AMQP协议的开源消息代理,具有高可靠性、灵活的路由功能和丰富的插件。
采用Erlang语言开发,支持集群和高可用性配置。
广泛应用于微服务架构、异步通信、消息分发和实时数据处理。
2.Apache Kafka
Kafka是Apache的分布式流处理平台,具有高吞吐量、低延迟、持久化和水平扩展能力。
架构:采用分区和副本机制,保证高可用和数据可靠性。
应用:适用于实时数据流处理、日志收集、事件驱动系统和大数据分析。
性能:极高的吞吐量和低延迟,适用于大规模数据流处理、和分析场景。
3.ActiveMQ
ActiveMQ是Apache基金会的开源消息中间件,支持JMS规范,具有高性能、可靠性和灵活性。
适用于中等到高负载的场景,性能较为稳定,但在超高吞吐量场景下可能不如Kafka。
4.RocketMQ
RocketMQ是Apache的分布式消息中间件,最早是阿里开发的,具有高性能、低延迟、可靠性和水平扩展性。
架构:基于分布式架构,支持顺序消息、事务消息和定时消息。
应用:广泛应用于金融、电子商务和大数据领域。
性能:高吞吐量和低延迟,适用于大规模消息处理和传输。
5.Apache Pulsar
Pulsar是Apache的分布式消息流平台,支持多租户、水平扩展和低延迟。
采用多层架构,分为存储层和计算层,支持分区和副本机制。
适用于实时数据处理、日志收集和事件流处理,具有高吞吐量、低延迟,适用于大规模实时数据流处理。
作者简介
陈睿|mikechen,10年+大厂架构经验,BAT资深面试官,就职于阿里巴巴、淘宝、百度等一线互联网大厂。
关注作者「mikechen」公众号,获取更多技术干货!
后台回复【架构】,即可获取《阿里架构师进阶专题全部合集》,后台回复【面试】即可获取《史上最全阿里Java面试题总结》