消息队列 RocketMQ 是阿里巴巴集团基于高可用分布式集群技术,自主研发的云正式商用的专业消息中间件,既可为分布式应用系统提供异步解耦 和削峰填谷的能力,同时也具备互联网应用所需的海量消息堆积、高吞吐、可靠重试等特性,是阿里巴巴双 11 使用的核心产品。
RocketMQ 的设计基于主题的发布与订阅模式,其核心功能包括消息发送、消息存储(Broker)、消息消费,整体设计追求简单与性能第一。
MQ:消息中间件是什么?
消息中间件属于分布式系统中一个子系统,关注于数据的发送和接收,利用高效可靠的异步消息传递机制对分布式系统中的其余各个子系统进行集成
NameServer 是整个 RocketMQ 的“大脑”,它是 RocketMQ 的服务注册中心,所以 RocketMQ需要先启动 NameServer 再启动 Rocket 中的 Broker。
Broker 在启动时向所有 NameServer 注册(主要是服务器地址等),生产者在发送消息之前先从 NameServer 获取 Broker 服务器地址列表(消费者一 样),然后根据负载均衡算法从列表中选择一台服务器进行消息发送。
NameServer与每台 Broker 服务保持长连接,并间隔 30S 检查 Broker 是否存活,如果检测到 Broker 宕机,则从路由注册表中将其移除。这样就可以实 现 RocketMQ 的高可用。具体细节后续的课程会进行讲解。
主题,Topic,消息主题,一级消息类型,生产者向其发送消息。消费者负责从 Topic 接收并消费消息。
生产者:也称为消息发布者,负责生产并发送消息至 Topic。
消费者:也称为消息订阅者,负责从 Topic 接收并消费消息。
消息:生产者或消费者进行消息发送或消费的主题,对于 RocketMQ 来说,消息就是字节数组。
以下我们将总结下 Rocket 的整体运转。
点我获取RocketMQ完整笔记-》》》》》》》》》》》》
整体设计思想 **80%**借鉴 Kafka.
基于主题的发布和订阅,其核心功能,消息发送、消息存储和消息消费。整体设计追求简单与性能。 NameServer 性能对比 Zookeeper 有极大的提升
高效的 IO 存储机制,基于文件顺序读写,内存映射机制
容忍设计缺陷,比如消息只消费一次,Rocket 自身不保证,从而简化 Rocket 的内核使得 Rocket 简单与高效,这个问题交给消费者去实现(幂等)。
架构模式:发布订阅模式,主要组件:消息发送者、消息服务器(消息存储)、消息消费、路由发现。
顺序消息:RocketMQ 可以严格保证消息有序
消息过滤:消息消费是,消费者可以对同一主题下的消息按照规则只消费自己感兴趣的消息,可以支持在服务端与消费端的消息过滤机制。
消息存储:一般 MQ 核心就是消息的存储,对存储一般来说两个维度:消息堆积能力和消息存储性能。RocketMQ 追求消息存储的高性能,引入内存映 射机制,所有的主题消息顺序存储在同一个文件中。同时为了防止无限堆积,引入消息文件过期机制和文件存储空间报警机制。
消息高可用:
普通消息是指消息队列 RocketMQ 中无特性的消息,区别于有特性的定时/延时消息、顺序消息和事务消息。这些后续会细讲。 RocketMQ 发送普通消息有三种实现方式:单向(OneWay)发送、可靠同步发送、可靠异步发送。
消息生产的客户端依赖如下:
broker.conf
#是否允许 **Broker** 自动创建 Topic,建议线下开启,线上关闭
autoCreateTopicEnable=true
#是否允许 Broker 自动创建订阅组,建议线下开启,线上关闭
autoCreateSubscriptionGroup=true
单向(Oneway)发送特点为发送方只负责发送消息,不等待服务器回应且没有回调函数触发,即只发送请求不等待应答。此方式发送消息的过程耗 时非常短,一般在微秒级别。cn.enjoyedu.normal.OnewayProducer
点我获取RocketMQ完整笔记-》》》》》》》》》》》》》》》》》》
生产者组,简单来说就是多个发送同一类消息的生产者称之为一个生产者组。在这里可以不用关心,只要知道有这么一个概念即可。RocketMQ 中的 生产者组只能有一个在用的生产者。分组的作用如下(简单的场景不需要了解这个概念):
Producer 的一个对象实例,不同的 Producer 实例可以运行在不同进程内或者不同机器上。Producer 实例线程安全,可在同一进程内多线程之间共 享。
Key 一般用于消息在业务层面的唯一标识。对发送的消息设置好 Key,以后可以根据这个 Key 来查找消息。比如消息异常,消息丢失,进行查找会很 方便。RocketMQ 会创建专门的索引文件,用来存储 Key 与消息的映射,由于是 Hash 索引,应尽量使 Key 唯一,避免潜在的哈希冲突。
Tag 和 Key 的主要差别是使用场景不同,Tag 用在 Consumer 代码中,用于服务端消息过滤,Key 主要用于通过命令进行查找消息
RocketMQ 并不能保证 message id 唯一,在这种情况下,生产者在 push 消息的时候可以给每条消息设定唯一的 key, 消费者可以通过 message key 保证对消息幂等处理。
消息标签,二级消息类型,用来进一步区分某个 Topic 下的消息分类。
Topic 与 Tag 都是业务上用来归类的标识,区分在于 Topic 是一级分类,而 Tag 可以理解为是二级分类。
以天猫交易平台为例,订单消息和支付消息属于不同业务类型的消息,分别创建 Topic_Order 和 Topic_Pay,其中订单消息根据商品品类以不同的 Tag 再进行细分,如电器类、男装类、女装类、化妆品类,最后他们都被各个不同的系统所接收。
通过合理的使用 Topic 和 Tag,可以让业务结构清晰,更可以提高效率。
您可能会有这样的疑问:到底什么时候该用 Topic,什么时候该用 Tag?
1)消息类型是否一致:如普通消息、事务消息、定时(延时)消息、顺序消息,不同的消息类型使用不同的 Topic,无法通过 Tag 进行区分。
2)业务是否相关联:没有直接关联的消息,如淘宝交易消息,京东物流消息使用不同的 Topic 进行区分;而同样是天猫交易消息,电器类订单、女 装类订单、化妆品类订单的消息可以用 Tag 进行区分。
3)消息优先级是否一致:如同样是物流消息,盒马必须小时内送达,天猫超市 24 小时内送达,淘宝物流则相对会慢一些,不同优先级的消息用不 同的 Topic 进行区分。
4)消息量级是否相当:有些业务消息虽然量小但是实时性要求高,如果跟某些万亿量级的消息使用同一个 Topic,则有可能会因为过长的等待时间 而“饿死”,此时需要将不同量级的消息进行拆分,使用不同的 Topic。
同步发送是指消息发送方发出数据后,同步等待,直到收到接收方发回响应之后才发下一个请求。
点我获取更多-》》》》》》》》》》》》》》》》》》
消息的全局唯一标识(内部机制的 ID 生成是使用机器 IP 和消息偏移量的组成,所以有可能重复,如果是幂等性还是最好考虑 Key),由消息队列 MQ 系统自动生成,唯一标识某条消息。
发送的标识。成功,失败等
RocketMQ 收到消息后,所有主题的消息都存储在 commitlog文件中,当消息到达 commitlog 后,将会采用异步转发到消息队列,也就是 consumerqueue, Queue 是数据分片的产物,数据分片可以提高消费者的效率。(这个也是 RocketMQ 对比 Kafka 的不同,存储设计时有队列的概念)
broker.conf
# 在发送消息时,自动创建服务器不存在的 topic,默认创建的队列数
defaultTopicQueueNums=4
消息发送方在发送了一条消息后,不等接收方发回响应,接着进行第二条消息发送。发送方通过回调接口的方式接收服务器响应,并对响应结果进 行处理
整理不易!点个关注,收藏一下吧!
点我获取RocketMQ完整笔记-》》》》》》》》》》》》》》》》》》