RocketMQ 消息队列
什么是消息队列?
消息队列顾名思义就是把消息放到一个队列里,从消息队列中获取消息的行为我们称之为消费,需要消费消息的消费者自行从消息队列中获取消息,那么就引出了消息队列的第一个特性——解耦。
- 解耦:如果没有消息队列:我们将服务A的消息发送给服务B和服务C,后续又新增了服务D需要服务A的消息,服务C不需要A的消息了,那么就需要对一个个服务进行具体的更改。在引入消息队列之后,我们只需要将消息丢到队列里,需要的自取就可以了,实现了服务的解耦。
先放到队列里,有需要的服务自取消息,那么这种模式又有什么特性呢?——异步。
异步:许多提交材料返回结果的操作都具有异步的特性,为什么需要异步性呢,因为同步的操作太耗费时间了,提交-->处理-->返回,如果是需要处理的请求特别多,那么返回的时间还会大幅增加,没有必要让用户持续等待,我们完全可以在用户提交后异步处理,处理完成后再通知用户。
异步处理拆解为:提交-->已经提交,处理-->处理完成,通知-->通知完成。三者中间通过消息队列串联起来就可以了,大大降低了每个请求的响应时间,提升了用户的体验。这就是消息队列的第二个用途,服务解耦。
异步意味着服务不必实时处理请求,那么这种模式又可以带来什么呢?——削峰。
- 削弱峰:当大量的请求涌入,这在生活中完全是可能的(秒杀、抢票等高并发场景),请求的波峰是无法避免的,同步的操作中服务器的负载也是随着请求而波动,但是异步操作使得我们可以根据服务器的能力均衡负载,请求存入消息队列-->服务器根据自己能力从中消费请求,使得系统负载稳定,避免大幅波动,保障服务正常运行。
几种消息队列
| 特性 | Kafka | ActiveMQ | RabbitMQ | RocketMQ |
|---|---|---|---|---|
| 功能支持 | 分布式、分区、高吞吐量、流处理、持久化 | JMS 支持、持久化、事务、消息过滤 | 消息路由、插件机制、持久化、多种协议支持 | 分布式、高吞吐量、事务、定时和延时消息、持久化 |
| 可用性 | 高(多副本机制、自动恢复) | 高(支持主从架构和多种持久化机制) | 高(镜像队列、集群模式) | 高(多副本机制、集群模式) |
| 消息可靠性 | 高(数据复制、多副本) | 高(持久化存储、事务支持) | 高(确认机制、持久化存储) | 高(数据复制、多副本、持久化存储) |
| 时效性 | 毫秒级(取决于配置和网络条件) | 毫秒级(取决于配置和网络条件) | 微秒级到毫秒级(取决于配置和网络条件) | 毫秒级(取决于配置和网络条件) |
| Topic 数量对吞吐量的影响 | 影响较大(分区机制带来管理和资源消耗) | 影响中等(队列管理开销) | 影响较小(高效的路由机制) | 影响中等(分区机制和管理开销) |
| 单机吞吐量 | 高(百万级消息每秒) | 中等(十万级消息每秒) | 中等(十万级消息每秒) | 高(百万级消息每秒) |
| Client SDK | 多语言(Java、Scala、Python 等) | 多语言(Java、C、C++ 等) | 多语言(Java、Erlang、.NET 等) | 多语言(Java、C++、Go 等) |
- 其中Kafaka适合大数据领域的实时计算、日志采集场景,因为性能最高。
- 对实时性有要求,不关心底层,用RabbitMQ即可。
- 阿里的RocketMQ经历过618、双11等节点的考验,且具有丰富的教程,一般使用RocketMQ就可以。
RocketMQ
官网的RocketMQ部署模型图
RocketMQ 四大核心组件
| 部署架构部分 | 功能描述 |
|---|---|
| 生产者(Producer) | 发布消息的角色。Producer 通过 MQ 的负载均衡模块选择相应的 Broker 集群队列进行消息投递,投递过程支持快速失败和重试机制。 |
| 消费者(Consumer) | 消息消费的角色。 - 支持 推(push) 和 拉(pull) 两种模式对消息进行消费。 - 支持 集群模式 和 广播模式 两种消费方式。 - 提供 实时消息订阅机制,可满足大多数用户的需求。 |
| 名称服务器(NameServer) | NameServer 是一个轻量级的 Topic 路由注册中心,支持 Topic、Broker 的动态注册与发现。 主要包含两个功能: ① Broker 管理:NameServer 接受 Broker 集群的注册信息并保存下来,作为路由信息的基础数据,并提供心跳检测机制检查 Broker 存活状态。 ② 路由信息管理:每个 NameServer 都会保存整个 Broker 集群的路由信息和客户端(Producer、Consumer)可查询的队列信息。Producer 和 Consumer 可通过 NameServer 获取 Broker 集群的路由信息,从而完成消息投递与消费。 此外,NameServer 通常会有多个实例部署,各实例之间互不通信。Broker 会向每台 NameServer 注册自己的路由信息,每个 NameServer 都保存完整副本。当某个 NameServer 下线时,客户端仍可从其他 NameServer 获取路由数据,保证系统高可用。 |
| 代理服务器(Broker) | Broker 负责 消息的存储、投递、查询,并保证服务的高可用。 - NameServer 为无状态节点,而 Broker 是集群的核心存储节点。 - 支持 Master–Slave 架构,Broker 可分为 Master 与 Slave。一个 Master 可对应多个 Slave,但每个 Slave 只能对应一个 Master。 - Master 与 Slave 的对应关系通过相同的 BrokerName 标识,不同的 BrokerId 区分(BrokerId=0 表示 Master,非 0 表示 Slave)。- 每个 Broker 节点独立存储数据,Master 节点也可以部署多个以实现更高吞吐与容灾能力。 |
RocketMQ 消息流转架构图
RocketMQ 消息流转时序图
为什么用RocketMQ?
RocketMQ是一个天然的分布式组件,对于分布式微服务来说很好用。
业务场景对延时性要求不高,可以用RocketMQ。