RocketMQ基础
为什么要用消息队列
解耦
生产者将消息放入消息队列,消费者从队列中取出消息,这样生产者与消费者就不会直接进行通信,这样也就实现了解耦,生产者只生产消息,消费者只消费消息
我的项目中的图片审批,就用了 RocketMQ 来做了解耦
异步
系统可以将那些耗时的任务放在消息队列中异步处理,以此达到快速响应用户请求的目的
比如说电商平台中,用户下单后,可以先返回一个下单成功的消息,然后将订单信息放在消息队列中,后台再去处理订单信息
削峰
用于应对系统高并发请求的瞬时流量高峰,通过消息队列,可以将瞬时的高峰流量转化为持续的低流量,从而保护系统不会因为瞬时的高流量而崩溃
用户将请求发送到系统后,由生产者接受并转换为消息,发送到 RocketMQ 中,队列用来充当缓存区,将大量请求按顺序排队,这样就可以削减请求高峰时对后端服务的直接压力
消费者从 RocketMQ 队列中按照一定速率读取消息并进行处理。可以根据后端处理能力和当前负载情况动态调整消费者的消费速率,达到填谷的效果
对 RocketMQ 的理解

RocketMQ 是阿里巴巴开源的一款分布式消息中间件,具有高吞吐量、低延迟和高可用性,其主要组件包括生产者、消费者、Brocker、Topic 和队列,消息由生产者发送到 Brocker,再根据路由规则存储到队列中,消费者从队列中拉取消息进行处理。适用于异步解耦和流量削峰等场景
消息队列有哪些模型
队列模型
这是一种发-存-收的模型,生产者往某个队列里发送消息,消费者从队列里获取消息,一个队列可以存储多个生产者的消息,也可以有多个消费者,但是消费者之间为竞争关系,换句话说,一个消息只能由一个消费者消费
发布/订阅模型
发布 - 订阅模型中,消息的发送方称为发布者(Publisher),消息的接收方称为订阅者(Subscriber),服务端存放消息的容器称为主题(Topic)
发布者将消息发送到主题中,订阅者接收消息前需要先订阅主题,订阅既是一个动作,同时也是主体在消费时创建的逻辑副本,每份订阅中,订阅者都可以接收到主题的所有消息
RocketMQ 的消息模型
RocketMQ 本身的消息是由下面几部分组成

Message
message 为要传输的消息
一个消息必须要有一个主题,主题可以看作是他要发送到的地址
Topic
topic 可以看作消息的归类,是消息的第一级类型
topic 可以有多个生产者向他发送消息,可以被多个消费者订阅,一个生产者也可以向不同的 topic 发送消息
Tag
tag 可以看作子主题,它是消息的第二级类型,用于为用户提供额外的灵活性
使用标签,同一业务模块不同目的的消息就可以用相同 Topic 而不同的 Tag 来标识
Group
订阅者的概念是通过消费组来体现的,每个消费组都消费主题中一份完整的消息,不同消费组之间的消费进度彼此独立
消费组中包含多个消费者,同一个组中的消费者是竞争消费关系
Message Queue
一个 Topic 下可以设置多个消息队列,Topic 包括多个 Message Queue,如果一个 Consumer 需要获取 Topic 下所有的消息,就要遍历所有的 Message Queue。
Offset
在 Topic 的消费过程中,由于消息需要被不同的组进行多次消费,所以消费完的消息并不会立即被删除,这就需要 RocketMQ 为每个消费组在每个队列上维护一个消费位置,这个位置之前的消息都被消费过,之后的消息都没有被消费过,每成功消费一条消息,消费位置就加一。
也可以这么说,Queue 是一个长度无限的数组,Offset 就是下标
消息的消费模式
消费模式有两种:Clustering(集群消费)和Broadcasting(广播消费)
默认为集群消费,一个消费者组共同消费一个主题的多个队列,一个队列只会被一个消费者消费,如果一个消费者失效,分组内其他的消费者会顶替
广播消费消息会发给消费者组中的每一个消费者进行消费
RocketMQ 的基本架构

RocketMQ 一共有四个部分组成:NameServer,Broker,Producer 生产者,Consumer 消费者,它们对应了:发现、发、存、收,为了保证高可用,一般每一部分都是集群部署的
如果类比,生产者消费者就是发信者和收信者,broker 就是邮局,NameServer 则是负责协调各个邮局的管理机构
NameServer
每个 NameServer 结点之间是相互独立,彼此没有任何信息交互。
Nameserver 被设计成几乎是无状态的,通过部署多个结点来标识自己是一个伪集群
Producer 在发送消息前从 NameServer 中获取 Topic 的路由信息,也就是发往哪个 Broker
Consumer 也会定时从 NameServer 获取 Topic 的路由信息
Broker 在启动时会向 NameServer 注册,并定时进行心跳连接,且定时同步维护的 Topic 到 NameServer
Broker
负责存储和转发消息
Broker 内部维护着一个个 Consumer Queue,用来存储消息的索引,真正存储消息的地方为 CommitLog
单个 Broker 与所有的 Nameserver 保持着长连接和心跳,并会定时将 Topic 信息同步到 NameServer,和 NameServer 的通信底层是通过 Netty 实现的
Producer
Producer由用户进行分布式部署,消息由Producer通过多种负载均衡模式发送到Broker集群,发送低延时,支持快速失败。
RocketMQ 提供了三种方式发送消息:同步、异步和单向
同步发送:同步发送指消息发送方发出数据后会在收到接收方发回响应之后才发下一个数据包。一般用于重要通知消息
异步发送:异步发送指发送方发出数据后,不等接收方发回响应,接着发送下个数据包,一般用于可能链路耗时较长而对响应时间敏感的业务场景
单向发送:单向发送是指只负责发送消息而不等待服务器回应且没有回调函数触发,适用于某些耗时非常短但对可靠性要求并不高的场景
Consumer
Consumer也由用户部署,支持 push 和 pull 两种消费模式,支持集群消费覅和广播消费
PULL为主动从消息服务器拉去信息,只要批量拉取到消息,用户应用会启动消费过程
Push推送型消费者封装了消息的拉取、消费进度和其他的内部维护工作,将消息到达时执行的回调接口留给用户应用程序来实现,不同于 Pull 的是 Push 首先要注册消费监听器,当监听器处触发后才开始消费消息