前言
本文源码以RocketMQ 4.2.0 和 RocketMQ 4.3.0 为 基 础 , 从RocketMQ的实际使用到RocketMQ的源码分析,再到RocketMQ企业落地实践方案,逐步讲解。使读者由浅入深地了解RocketMQ。
本文在源码分析过程中,先讲整体流程,再按模块、步骤进行详细讲解,希望读者在阅读时能举一反三,能知其然且知其所以然。
本文总共九章,分为五部分,第一部分讲解消息队列入门和RocketMQ生产、消费原理与最佳实践;第二部分从整体角度讲解RocketMQ架构;第三部分讲解RocketMQ各个组件的基本原理;第四部分深入RocketMQ,讲解如何阅读源代码、如何进行企业实践;第五部分是附录,包含Namesrv、Broker的核心参数配置说明和Exporter监控指标注释。
目录
主要内容
第1章RoketMQ综述;
- 1.1什么是消息队列,消息队列(Message Queue),从广义上讲是一种消息队列服务中间件,提供一套完整的信息生产、传递、消费的软件系统。
- 1.2为什么需要消息队列,通过上一节的讲解,相信读者对消息队列有了一个初步的认识,那么我们平时什么时候可能会用到消息队列呢?
- 1.3常见消息队列,
- 1.4 RocketMQ的发展史与未来,Apache RocketMQ是一款开源的、分布式的消息投递与流数据平台。出生自阿里巴巴,在阿里巴巴内部经历了3个版本后,作为Apache顶级开源项目之一直到现在。在GitHub上有10000+star、5000+fork、170+contributors(在GitHub上提交代码并被采纳的开发者),目前的最新版本是2020年3月的4.7.0版本。本节主要介绍RocketMQ的产生和成长过程。
第2章RocketMQ的生产者原理和最佳实践;
- 2.1生产者原理,通过第1章的讲解,相信读者对RocketMQ有了一个基本的认识,本节将对RocketMQ中的生产者做基本介绍。
- 2.2生产者启动流程,DefaultMQProducer 是 RocketMQ 中默认的生产者实现 ,DefaultMQProducer的类之间的继承关系,可以看到这个生产者在实现时包含生产者的操作和配置属性,这是典型的类对象设计。本节将介绍类对象的一些核心属性和方法。
- 2.3消息发送流程,消息发送流程首先是 RocketMQ 客户端接收业务层消息,然后通过DefaultMQProducerImpl发送一个RPC请求给Broker,再由Broker处理请求并保存消息。
- 2.4发送消息最佳实践,发送普通消息、顺序消息、延迟消息、事务消息、单向消息、批量消息发送。
- 2.5生产者最佳实践总结,相对消费者而言,生产者的使用更加简单,一般读者主要关注消息类型、消息发送方法和发送参数,即可正常使用RocketMQ发送消息。
在实际使用时如何选择消息类型和消费发送方法呢?笔者在这里总结了常用的消息类型、消息发送方法、发送基本参数,方便大家参考。
第3章RocketMQ的消费流程和最佳实践;
- 3.1消费者概述,消费者一般指获取消息、转发消息给业务代码处理的一系列代码实现。在 RocketMQ中,消费行为是如何进行的呢?本节将详细讲述。
- 3.2消费者启动机制,RocketMQ 客户端中有两个独立的消费者实现类 :org.apache.rocketmq.client.consumer.DefaultMQPullConsumer和org.apache.rocketmq.client.consumer.DefaultMQPushConsumer 。 下面将分别进行介绍。
- 3.3消费者的Rebalance机制,客户端是通过Rebalance服务做到高可靠的。当发生Broker掉线、消费者实例掉线、Topic 扩容等各种突发情况时,消费者组中的消费者实例是怎么重平衡,以支持全部队列的正常消费的呢?
- 3.4消费进度保存机制,在消费者启动时会同时启动位点管理器,那么位点具体是怎么管理的呢?RocketMQ 设计了远程位点管理和本地位点管理两种位点管理方式。集群消费时,位点由客户端提交给Broker保存,具体实现代码在RemoteBrokerOffsetStore.java文件中;广播消费时 ,位 点 保 存在消费者本地磁盘上 , 实现代码在LocalFileOffsetStore.java文件中。
- 3.5消费方式,RocketMQ的消费方式包含Pull和Push两种。Pull方式:用户主动Pull消息,自主管理位点,可以灵活地掌控消费进度和消费速度,适合流计算、消费特别耗时等特殊的消费场景。
缺点也显而易见,需要从代码层面精准地控制消费,对开发人员有一定要求。在RocketMQ中org.apache.rocketmq.client.consumer.DefaultMQPullConsumer 是 默认的Pull消费者实现类。Push 方式:代码接入非常简单,适合大部分业务场景。缺点是灵活度差,在了解其消费原理后,排查消费问题方可简单快捷。在RocketMQ中org.apache.rocketmq.client.consumer.DefaultMQPushConsumer 是 默认的Push消费者实现类。 - 3.6消息过滤
- 3.7消费者最佳实践总结,本章主要介绍了消费流程和消费者原理、过滤器的设计和执行过程。Pull 和 Push 在使用中有两点特别需要注意:订阅关系不一致和不能消费时怎么排查,这里分享一下笔者在实践过程中的经验。
第4章RocketMQ架构和部署最佳实践;
4.1 RocketMQ架构,RocketMQ 不单单是一个技术,它还是一个体系。
4.2常用的部署拓扑和部署实践,常用的RocketMQ的部署拓扑方式有5种,不同的部署方式可靠性不同,大家在公司落地部署时,可以根据企业业务的需求进行选择,或者有新的部署方式也可以分享给笔者和RocketMQ社区。
第5章Namesrv;
- 5.1 Namesrv概述,Namesrv在RocketMQ体系中主要用于保存元数据、提高Broker的可用性。
在 RPC 通信中,我们通常将服务提供者称为服务端,使用服务的端称为客户端。如果服务端有扩容或缩容,客户端如何感知呢?业内常用的做法是,服务注册与发现。通过注册,可以添加更多提供服务的服务端实例,当然有实例宕机,也可以通过摘除来保证服务的可靠性。Broker作为RocketMQ服务的提供者,其工作原理也是一样的。 - 5.2 Namesrv架构,Namesrv组件,Namesrv启动流程,Namesrv停止流程;
- 5.3 RocketMQ的路由原理,生产者发送消息、消费者消费消息时都需要从Namesrv拉取Topic路由信息,那么这些路由信息是如何注册到 Namesrv的呢?如果 Broker 异常宕机,路由信息又是如何更新的呢?
下面,我们通过路由注册和路由剔除两个方面进行详细讲解。
第6章Broker存储机制;
- 6.1 Broker概述,本章主要讲解了 Broker的基本知识,以及 Broker在体系中所处的地位。带领读者从部署结果上看Broker的各个文件目录结构,为下一章学习存储模块打下基础。本章的核心内容有:● Broker在RocketMQ体系中所处的地位。● Broker的数据目录结构。● Broker的启动和停止流程。
- 6.2 Broker存储机制,堆积能力是消息队列的一个重要考核指标。存储机制是RocketMQ中的核心,也是亮点设计,因为存储机制决定写入和查询的效率。
- 6.3 Broker CommitLog索引机制,绝大部分存储组件都有索引机制,RocketMQ 也一样,有巨量堆积能力的同时,通过索引可以加快读取和查询。
本节主要讲解RocketMQ的ConsumeQueue和IndexFile两种索引的基本原理:● 索引的数据结构。● 索引的构建过程。● 索引如何使用。 - 6.4 Brokeri过期文件删除机制,RocketMQ中主要保存了CommitLog、Consume Queue、Index File三种数据文件。由于内存和磁盘都是有限的资源,Broker不可能永久地保存所有数据,所以一些超过保存期限的数据会被定期删除。RocketMQ 通过设置数据过期时间来删除额外的数据文件,具体的实现逻辑是通过org.apache.rocketmq.store.DefaultMessageStore.start()方法启动的周期性执行方法DefaultMessageStore.this.cleanFilesPeriodically()来实现的。
- 6.5 Broker主从同步机制,当前主流的分布式组件中,可用性都是必备的。本节主要讲RocketMQ中可用性的设计和实现方式,主要内容有如下两个方面:● 主从同步介绍。● 主从同步流程。
- 6.6 Broker的关机恢复机制,可靠性也是当前主流分布式产品的必备特性之一,对于一个金融级可靠的消息队列组件来讲更是如此。本节主要讲解内容如下:● 关机恢复机制的相关文件和实现原理。● 关机恢复机制的恢复过程。
第7章RocketMQ特性——事务消息与延迟消息机制;
- 7.1事务消息概述,事务消息的实现方案目前主要分为两种:两阶段提交方案和三阶段提交方案。RocketMQ 采取了两阶段提交的方案进行实现,事务消息的代码讲解基于4.3.0版本。
- 7.2事务消息机制,我们将事务消息的发送和处理总结为四个过程:生产者发送事务消息和执行本地事务、Broker存储事务消息、Broker回查事务消息、Broker提交或回滚事务消息。接下来,我们对这四个过程进行详细讲解。
- 7.3延迟消息概述,什么是延迟消息呢?延迟消息也叫定时消息,一般地,生产者在发送消息后,消费者希望在指定的一段时间后再消费。常规做法是,把信息存储在数据库中,使用定时任务扫描,符合条件的数据再发送给消费者。下面通过一个春节买票的场景来进行讲解。
- 7.4延迟消息机制,在RocketMQ 4.3.0支持延迟消息前,开源版本RocketMQ延迟消息机制就是一个谜,本节将基于RocketMQ 4.3.0为大家揭秘延迟消息的存储和投递机制。
第8章RocketMQ源代码阅读;
- 8.1 RocketMQ源代码结构概述,Apache RocketMQ 项目是一个基于 maven 构建的多模块 Java 项目,将源代码导入IntelliJ IDEA;
- 8.2 RocketMQ源代码编译;
- 8.3如何阅读源代码,
- 8.4 源代码阅读范例:通过消息id查询消息,在RocketMQ Console中,我们发现可以通过消息id查询消息体内容,接下来我们看看具体是怎么查询的,
第9章RocketMQ企业最佳实践;
- 9.1 RocketMQ落地概述,
- 9.2 RocketMQ集群管理,Topic 管理是集群管理中常见的操作,包括创建 Topic、查看Topic 路由、修改 Topic配置、重置消费位点。在上一节中主要讲解了如何管理 Topic,本节主要讲解如何管理消费者。通常消费者管理就是指消费者组管理和消费者实例管理,关于消费者组和消费者实例的相关概念在第4章已做详细描述。
- 9.3 RocketMQ集群监控和报警,对于RocketMQ的监控分为硬件监控和软件监控。硬件监控一般是机器内存使用率、CPU使用率、磁盘使用率等主机监控;软件监控是Namesrv、Broker、客户端生产、消费的指标数据监控和报警。一般运维的读者会默认添加主机监控,这里笔者主要介绍基于Prometheus的软件监控和报警。
- 9.4 RocketMQ集群迁移,RocketMQ 的集群迁移特指 Namesrv、Broker 的迁移。一般企业需求需要满足两点:对研发透明、消息不丢失。Namesrv机器之间因为是无状态的,所以迁移相对简单,在这里我们主要介绍如何迁移Broker集群。
Broker集群迁移可以采用 Topic扩容的方式进行。具体的迁移过程笔者总结为 - 9.5 RocketMQ测试环境实践9.6 RocketMQ接入实践,为什么需要单独讲测试环境呢?消息队列中间件的最终用户都是公司的研发人员,测试环境也是研发使用最频繁的环境,自然也是问题最多的。测试环境为了研发人员方便会有多个子环境,这与RocketMQ中订阅关系必须保持一致的规则相冲突,导致不同环境的消费者“抢消费”的情况发生。本节我们主要讲一下“抢消费”问题。
希望读者在平时的工作中能熟悉、借鉴、参考RocketMQ的优秀设计理念,在技术能力上更进一步,在工作中更好地服务公司。