消息队列(Message Queue),指保存消息的一个容器,本质是个队列,使用消息队列主要是为了通过异步处理提高系统性能和削峰、降低系统耦合性。
向消息队列中存放数据的叫做生产者,从消息队列中获取数据的叫做消费者。
应用场景
异步处理
比如用户注册的例子,用户注册成功后,系统需要发送注短信注册成功通知,以及赠送注册成功的积分。 假设用户注册消耗10ms,发送短信需要100ms,赠送积分需要100ms 那么整个流程的同步总耗时为:10ms+100ms+100ms=210ms 如果将其改造为异步处理,用户注册后通过消息队列处理,分成了发送短信和增加积分两个异步处理模块。这样一来,用户只需要10ms就可以得到反馈,而无需等待耗时较久的同步。
解耦
使用了消息队列后,只要保证消息格式不变,消息的发送方和接收方并不需要彼此联系,也不需要受对方的影响,只通过消息队列MQ来联系:上游服务发送消息到消息队列,消息队列将其解耦,分给不同的下游服务供它们消费。
削锋
应用场景通常在电商平台的秒杀或团购活动中。 系统的峰值流量往往集中于一小段时间内,为了防止系统在短时间内的峰值流量冲垮,往往采用消息队列来削弱峰值流量,相当于消息队列做了一次缓冲。
日志处理
指将消息队列用在日志处理中,如Kafka的应用,解决大量日志传输的问题。
消息队列设计
整体架构由三个部分:
1)Producer 消息生产者:负责产生和发送消息到 Broker;
2)Broker 消息处理中心:负责消息存储、确认、重试等,一般其中会包含多个 queue;
3)Consumer 消息消费者:负责从 Broker 中获取消息,并进行相应处理。
第一步中,Producer生产消息向Broker发送会涉及到通信的问题,同样Consumer 消费消息也会涉及到通信的问题。一般使用RPC通信。
第二步中,消息到达服务端后需要存储到Broker。比如流量削峰,最终需求是需要Broker先存储下来,然后选择时机投递,这才达到流量削峰、泄洪的目的,所以对于Broker来说,一个非常重要的功能就是存储。
第三步中,消息到达Broker后,最终需要Consumer去消费消息,这里就会涉及到到消费模型。
消费模型,主要有两种:单播和广播。所谓单播,就是点到点;而广播,是一点对多点。
消息队列模型
1.点对点模型
用于消息生产者和消息消费者之间点到点的通信,包含三个角色:
- 消息队列(Queue)
- 发送者(Sender)
- 接收者(Receiver)
每个消息都被发送到一个特定的队列,接收者从队列中获取消息。队列保留着消息,可以放在内存中也可以持久化,直到他们被消费或超时。
- 每个消息只有一个消费者(Consumer)(即一旦被消费,消息就不再在消息队列中)
- 发送者和接收者之间在时间上没有依赖性
- 接收者在成功接收消息之后需向队列应答成功
2.发布订阅消息模型Topic
发布订阅模型包含三个角色:
- 主题(Topic)
- 发布者(Publisher)
- 订阅者(Subscriber)
多个发布者将消息发送到Topic,系统将这些消息传递给多个订阅者。
- 每个消息可以有多个消费者:和点对点方式不同,发布消息可以被所有订阅者消费
- 发布者和订阅者之间有时间上的依赖性。
- 针对某个主题(Topic)的订阅者,它必须创建一个订阅者之后,才能消费发布者的消息。
- 为了消费消息,订阅者必须保持运行的状态。
消息队列产品
1.ActiveMQ
官网地址:activemq.apache.org
Apache出品,性能在万级/秒。
2.RabbitMQ
官网地址:www.rabbitmq.com 由erlang语言开发,结合erlang语言本身的并发优势,支持很多的协议:AMQP,XMPP, SMTP, STOMP,性能在万级/秒,
3.Kafka
官网地址:kafka.apache.org
Kafka是一个分布式的、分区的、多复本的日志提交服务,性能在百万级/秒。
4.BMQ
BMQ 是字节跳动出品的消息队列产品,解决了 Kafka 在实际应用中的诸多问题。兼容 Kafka 协议,支持存算分离,支持云原生消息队列。