【深入浅出之透析RocketMQ原理及实战指南】精讲RocketMQ是什么 | 带你真正认识RocketMQ

1,176 阅读8分钟

本文正在参加「金石计划 . 瓜分6万现金大奖」 

名言警句

阅读使人充实,会谈使人敏捷,写作使人精确。——培根

前提概要

RocketMQ是一个统一消息引擎、轻量级数据处理平台。RocketMQ是一款阿里巴巴开源的消息中间件。 2016 年 11 月 28 日,阿里巴巴向 广西党性培训 Apache 软件基金会捐赠RocketMQ,成为 Apache 孵化项目。 2017 年 9 月 25 日,Apache 宣布 RocketMQ孵化成为 Apache 顶级项目(TLP ),成为国内首个互联网中间件在 Apache 上的顶级项目。

image.png

文章宗旨

本系列文章主要针对于RocketMQ的多个关键特性的实现原理进行深入介绍,并对消息中间件遇到的各种问题进行总结,阐述 RocketMQ如何解决这些问题。

消息中间件(MQ)的最基础的协议常见协议

一般情况下MQ的实现是要遵循一些常规性协议的。常见的协议如下:

JMS

JMS,Java Messaging Service(Java消息服务)。是Java平台上有关MOM(Message OrientedMiddleware,面向消息的中间件 PO/OO/AO)的技术规范,它便于消息系统中的Java应用程序进行消息交换,并且通过提供标准的产生、发送、接收消息的接口,简化企业应用的开发。ActiveMQ是该协议的典型实现。

STOMP

STOMP,Streaming Text Orientated Message Protocol(面向流文本的消息协议),是一种MOM设计的简单文本协议。STOMP提供一个可互操作的连接格式,允许客户端与任意STOMP消息代理(Broker)进行交互。ActiveMQ是该协议的典型实现,RabbitMQ通过插件可以支持该协议。

AMQP

AMQP,Advanced Message Queuing Protocol(高级消息队列协议),一个提供统一消息服务的应用层标准,是应用层协议的一个开放标准,是一种MOM设计。基于此协议的客户端与​​消息中间件​​可传递消息,并不受客户端/中间件不同产品,不同开发语言等条件的限制。 RabbitMQ是该协议的典型实现。

MQTT

MQTT,Message Queuing Telemetry Transport(消息队列遥测传输),是IBM开发的一个即时通讯协议,是一种二进制协议,主要用于服务器和低功耗IoT(物联网)设备间的通信。该协议支持所有平台,几乎可以把所有联网物品和外部连接起来,被用来当做传感器和致动器的通信协议。 RabbitMQ通过插件可以支持该协议。

CORBA Notification

不太理解,没怎么研究过

RocketMQ的设计优势

上面的基本协议为设计MQ系统指明了方向,但是仍有不少问题规范没有提及,对于消息中间件又至关重要。RocketMQ 并不遵循任何规范,但是参考了各种规范与同类产品的设计思想,可所谓“去其糟粕,取其精华”。

RocketMQ的最初用途

在阿里孕育 RocketMQ 的雏形时期,我们将其用于异步通信、搜索、社交网络活动流、数据管道,贸易流程中。随着我们的贸易业务吞吐量的上升,源自我们的消息传递集群的压力也变得紧迫。

根据我们的研究,随着队列和虚拟主题使用的增加,ActiveMQ IO模块达到了一个瓶颈。我们尽力通过节流、断路器或降级来解决这个问题,但效果并不理想。于是我们尝试了流行的消息传递解决方案Kafka。不幸的是,Kafka不能满足我们的要求,其尤其表现在低延迟和高可靠性方面,详见这里。在这种情况下,我们决定发明一个新的消息传递引擎来处理更广泛的消息用例,覆盖从传统的pub/sub场景到高容量的实时零误差的交易系统。

       Apache RocketMQ 自诞生以来,因其架构简单、业务功能丰富、具备极强可扩展性等特点被众多企业开发者以及云厂商广泛采用。历经十余年的大规模场景打磨,RocketMQ 已经成为业内共识的金融级可靠业务消息首选方案,被广泛应用于互联网、大数据、移动互联网、物联网等领域的业务场景。

RocketMQ产品发展历史

最原始的发展阶段主要过度了五个主要版本

1.0版本Metaq(Metamorphosis)

由开源社区 killme2008 维护,开源社区非常活跃。项目仓库地址:​​https://github.com/killme2008/Metamorphosis ​

2.0版本Metaq

由2012 年 10 月份上线,在淘宝内部被广泛使用。

3.0版本RocketMQ

​基于公司内部开源共建原则, RocketMQ项目只维护核心功能,且去除了所有其他运行时依赖,核心功能最简化。每个 BU 的个性化需求都在 RocketMQ 项目之上进行深度定制。RocketMQ 向其他 BU 提供的仅仅是 Jar 包,例如要定制一个 Broker,那么只需要依赖 rocketmq-broker 这个 jar 包即可,可通过 API 进行交互, 如果定制 client,则依赖 rocketmq-client 这个 jar 包,对其提供的 api 进行再封装。 开源社区地址:​ ​​https://github.com/alibaba/RocketMQ ​

4.0版本RocketMQ

目前用的最多的,我用的主要是4.3、4.5、4.9.2这几个版本。

5.0版本RocketMQ

最新版本,还在尝试学习中。

RocketMQ的基本属性

Producer

消息生产者,负责产生消息,一般由业务系统负责产生消息。

Consumer

消息消费者,负责消费消息,一般是后台系统负责异步消费。

Push Consumer

刻回调 Listener 接口方法。

Pull Consumer

Consumer 的一种,应用通常主动调用 Consumer 的拉消息方法从 Broker 拉消息,主动权由应用控制。

Producer Group

一类 Producer 的集合名称,这类 Producer 通常发送一类消息,且发送逻辑一致。

Consumer Group

      一类 Consumer 的集合名称,这类 Consumer 通常消费一类消息,且消费逻辑一致。

Broker

     消息中转角色,负责存储消息,转发消息,一般也称为 Server。在 JMS 规范中称为 Provider。

广播消费

      一条消息被多个 Consumer 消费,即使这些 Consumer 属于同一个Consumer Group,消息也会被 Consumer  Group 中的每个 Consumer 都消费一次,广播消费中的 Consumer Group 概念可以认为在消息划分方面无意 义。

集群消费

一个Consumer Group 中的 Consumer 实例平均分摊消费消息。例如某个 Topic 有 9 条消息,其中一个 Consumer Group 有 3 个实例(可能是 3 个进程,或者 3 台机器),那么每个实例只消费其中的 3 条消息。

  • 在 CORBA Notification 规范中,无此消费方式。
  • 在 JMS 规范中,JMS point-to-point model 与之类似,但是 RocketMQ 的集群消费功能大等于 PTP 模型。 因为 RocketMQ 单个 Consumer Group 内的消费者类似于 PTP,但是一个 Topic/Queue 可以被多个 Consumer Group 消费。

顺序消息

消费消息的顺序要同发送消息的顺序一致,在 RocketMQ 中,主要指的是局部顺序,即一类消息为满足顺序性,必须 Producer单线程顺序发送,且发送到同一个队列,这样 Consumer 就可以按照 Producer 发送 的顺序去消费消息。

普通顺序消息

顺序消息的一种,正常情况下可以保证完全的顺序消息,但是一旦发生通信异常,Broker 重启,由于队列 总数发生变化,哈希取模后定位的队列会变化,产生短暂的消息顺序不一致。 如果业务能容忍在集群异常情况(如某个 Broker 宕机或者重启)下,消息短暂的乱序,使用普通顺序方式比较合适。

严格顺序消息

顺序消息的一种,无论正常异常情况都能保证顺序,但是牺牲了分布式 Failover 特性,即 Broker 集群中只 要有一台机器不可用,则整个集群都不可用,服务可用性大大降低。 如果服务器部署为同步双写模式,此缺陷可通过备机自动切换为主避免,不过仍然会存在几分钟的服务不可用。(依赖同步双写,主备自动切换,自动切换功能目前还未实现)

目前已知的应用只有数据库 binlog 同步强依赖严格顺序消息,其他应用绝大部分都可以容忍短暂乱序,推 荐使用普通的顺序消息。

Message Queue

在RocketMQ 中,所有消息队列都是持久化,长度无限的数据结构,所谓长度无限是指队列中的每个存储单元都是定长,访问其中的存储单元使用 Offset 来访问,offset 为 java long 类型,64 位,理论上在 100 年内不会溢出,所以认为是长度无限,另外队列中只保存最近几天的数据,之前的数据会按照过期时间来删除。 也可以认为 Message Queue 是一个长度无限的数组,offset 就是下标。