RocketMQ基础知识点

这里写自定义目录标题

  • 1、消息队列与RocketMQ简介
    • 1.1 消息队列要解决的问题
      • 1.1.1 发布/订阅
      • 1.1.2 消息优先级
      • 1.1.3 消息顺序
      • 1.1.4 消息过滤
      • 1.1.5 消息持久化
      • 1.1.6 消息可靠性
      • 1.1.7 低延迟发送消息
      • 1.1.8 消息必须投递一次
      • 1.1.9 仅发送/消费一次
      • 1.1.10 Broker的Buffer满了怎么办
      • 1.1.11 回溯消费
      • 1.1.12 消息堆积
      • 1.1.13 分布式事务消息
      • 1.1.14 定时消息
      • 1.1.15 消息重试
    • 1.2 RocketMQ演变历史
    • 1.3 RocketMQ过往表现
    • 1.4 RocketMQ环境要求
    • 1.5 RocketMQ术语
    • 1.6 RocketMQ物理部署结构
    • 1.7 RocketMQ逻辑部署结构
  • 2、RocketMQ设计原理
    • 2.1 服务端架构
    • 2.2 客户端架构
    • 2.3 数据模型

1、消息队列与RocketMQ简介

1.1 消息队列要解决的问题

这里参考CORBA Notification规范对消息队列的要求做简单介绍。

1.1.1 发布/订阅

发布/订阅是消息队列的基本功能。消息发布者并不会主动地发送消息给特定的订阅者,不需要知道发布的消息会由哪些订阅者消费,只需要将消息分为不同的类别即可。而订阅者也不需要知道消息的发布者是谁,只需要订阅自己感兴趣的消息。

1.1.2 消息优先级

即在一个消息队列中,每条消息都有对应的优先级,一般用整数来描述,优先级高的消息先投递。如果消息完全在一个内存队列中,只需按优先级进行排序即可。
由于RocketMQ的所有消息都是持久化到磁盘的,所以按照优先级排序会有很大的性能开销。因此RocketMQ没有特意支持消息优先级。
但是,若业务中确实需要消息优先级的场景怎么办呢?也不是没有办法,可以将不同的队列分为不同的优先级级别,那么,在发送消息时就发送到对应级别的队列上即可。但是,因为网络、单点故障等原因,这种方式并不能确保严格的优先级。

1.1.3 消息顺序

消息有序指一类消息消费时,能按照发送的顺序来消费。例如:一个订单产生了3条消息,分别是订单创建、订单付款、订单完成。消费时,要按照这个顺序消费才能有意义。RocketMQ可以严格地保证消息有序。

1.1.4 消息过滤

包括Broker端过滤和Consumer端过滤。Broker端过滤,即按照Consumer的要求做过滤,优点是减少了对于Consumer无用消息的网络传输,缺点是增加了Broker的负担,且实现也相对复杂。Consumer端过滤,可由消费方自定义实现,但缺点是很多无用的消息需要传输到Consumer端。

1.1.5 消息持久化

消息中间件通常采用的几种持久化方式:

(1)持久化到数据库
(2)持久化到KV存储
(3)文件记录形式(Kafka和RocketMQ均采用此方式)
(4)对内存数据做一个持久化镜像。

1.1.6 消息可靠性

影响消息可靠性的几种情况:

(1)Broker正常关闭
(2)Broker异常Crash
(3)OS Crash
(4)机器断电,但能立即恢复供电
(5)机器无法开机(比如CPU、主板、内存等关键设备损坏)
(6)磁盘损坏
其中,(1)、(2)、(3)和(4)四种情况属于硬件资源可立即恢复的情况,RocketMQ可保证消息不丢,或仅丢失少量数据(异步刷盘时)。(5)和(6)属于单点故障,且无法恢复,一旦发生,消息全部丢失。在RocketMQ中,当使用异步复制时,可保证99%的消息不丢,但仍然会有少量消息丢失;当使用同步双写技术时,可完全避免消息丢失,但会严重影响性能,适合对消息可靠性要求极高的场合。

1.1.7 低延迟发送消息

在消息不堆积的情况下,消息到达Broker后,能立即到达Consumer。RocketMQ使用长轮询PULL方式,可保证消息的实时性。

1.1.8 消息必须投递一次

RocketMQ Consumer先PULL消息到本地,消费完成后,才向服务器返回ACK,如果没有消费就一定不会返回ACK,以此确保每条消息被投递一次。

1.1.9 仅发送/消费一次

即不允许重复发送/消费消息,如果要确保这一点,在分布式环境下会有巨大的性能开销。所以,为了追求高性能,RocketMQ并不保证此特性,要求业务方自己去重,也就是消费消息要做到幂等性。

1.1.10 Broker的Buffer满了怎么办

Broker的Buffer通常指Broker中一个队列的内存Buffer大小,这类Buffer通常是有大小限制的,如果Buffer满了之后一般有以下处理方式:

(1)拒绝新来的消息,向Producer返回RejectNewEvents错误码。
(2)按照特定策略丢弃
a)丢失到达的所有消息
b)最先到达的消息最先丢弃
c)最晚到达的消息最先丢弃
d)优先级最低的消息最先丢弃
e)最接近过期的消息最先丢弃
RocketMQ没有内存Buffer概念,RocketMQ的队列都是持久化磁盘,数据定期清除。对于此问题的解决思路,RocketMQ同其他MQ有非常显著的区别,RocketMQ的内存Buffer抽象成一个无限长度的队列,不管有多少数据进来都能装得下,这个无限是有前提的,Broker会定期删除过期的数据。

1.1.11 回溯消费

回溯消费指Consumer需要消费已经被消费过的消息。Broker在接收到Consumer的投递成功消息后,消息仍需要保留。RocketMQ支持按照时间回溯消费,时间维度精确到毫秒,可以向前或向后回溯。

1.1.12 消息堆积

消息中间件的主要功能是异步解耦,还有个重要的功能是挡住前端的数据洪峰,保证后端系统的稳定性,这就要求消息中间件具有一定的消息堆积能力:

(1)消息堆积在内存Buffer,一旦超过内存Buffer,可以根据一定的丢弃策略来丢弃消息,这种情况对性能影响不大。
(2)消息堆积到持久化存储系统中,当消息不能在内存Cache命中时,就要访问磁盘,会产生大量读磁盘IO,将直接影响消息堆积后的访问能力。

1.1.13 分布式事务消息

RocketMQ使用XA的二阶段提交协议来实现事务消息,具体的内容后文会介绍。

1.1.14 定时消息

定时消息指消息发送到Broker后,不能立即被Consumer消费,要等到特定的时间点才能被消费。
RocketMQ支持定时消息,但不支持任意时间精度,仅支持特定的时间,比如5s、10s或1m等。若要支持任意的时间精度,在Broker层面,必须要对消息进行排序,而由于消息被持久化到磁盘中的,会造成极大的性能开销。

1.1.15 消息重试

Consumer消费消息失败后,要提供一种重试机制。Consumer消费失败通常有以下两种情况:

(1)消息自身原因,例如反序列化失败,消息数据被损坏(比如手机号码被冻结,充值失败)。这种情况如果立即重试,大部分情况下也会失败,所以最好提供一种定时重试的机制,比如10s后重试。
(2)业务方依赖的服务不可用,这种情况立即重试也一般同样服务不可用,可以间隔比较长的时间再重试,比如30s后重试。

1.2 RocketMQ演变历史

(1)Notify 从单机到分布式的改造,淘系订单等交易核心异步消息场景使用。
(2)Napoli B2B基于ActiveMQ开发的消息引擎。
(3)MetaQ v1.0 基于Kafka开发的顺序消息队列,使用Java重写,有安全等问题,后来有了MetaQ v2.0。
(4)MetaQ v3.0 RocketMQ v3.0 重写了MetaQ,将内核抽出来RocketMQ开源,以拉模式为主,兼有推模式的高性能、低延迟消息引擎。
(5)Aliware MQ v1.0 Notify v3.0 都以RocketMQ作为内核,主要用于交易系统,Aliware用于阿里云。
(6)Apache开源RocketMQ。

1.3 RocketMQ过往表现

RocketMQ基础知识点_第1张图片

1.4 RocketMQ环境要求

  • 推荐使用Linux/Unix/Mac 64bit OS;
  • 64bit JDK 1.8+;
  • Maven 3.2.x
  • Git
    如果读者想要自己搭建一个RocketMQ环境来研究或学习,建议采用Linux或者Mac操作系统,具体的部署方法请前往RocketMQ官网了解。由于笔者办公电脑是Windows的,而又不想安装VM Ware等消耗硬件资源严重的虚拟机,因此在Windows环境下基于centos制作了一个RocketMQ的Docker镜像,但RocketMQ并不能在Windows的Docker容器环境下正常运行,应该是因为RocketMQ的所有设计都是基于Linux体系所造成的,若是对这方面比较熟悉的同学欢迎在文章末尾留言。笔者在Linux操作系统下,以及MacOS上部署RocketMQ一切顺利。

1.5 RocketMQ术语

(1)Producer:消息生产者,负责生产消息。
(2)Consumer:消息消费者,负责消费消息。
(3)Push Consumer:Consumer的一种,业务方通常为Consumer对象注册一个Listener,一旦收到消息,Consumer立即回调Listener接口方法。
(4)Pull Consuler:Consumer的一种,业务方主动调用Consumer拉消息。
(5)Producer Group:一类Producer的集合名称,通常为一个业务系统的标识。
(6)Consumer Group:一类Consumer的集合名称,通常为一个业务系统的标识。
(7)Broker:负责消息的存储与转发。
(8)广播消费:一条消息可以被多个Consumer消费,即使这些Consumer属于同一个Consumer Group,消息也会被Consumer Group中的每个Consumer都消费一次。
(9)集群消费:一个Consumer Group中的每个Consumer实例平均分摊消费消息。
(10)顺序消息:消息的消费顺序同发送顺序保持一致,在RocketMQ中,为满足顺序性,Producer必须单线程顺序发送,且发送到同一个队列,Consumer就可以按照Producer发送的顺序去消费消息。
(11)普通顺序消息:即正常情况下可以保证消息的顺序性,但在Broker重启等情况下,由于队列数目发生变化,可能就会在某段时间里不能保持消息的顺序性。
(12)严格顺序消息:完全保证顺序性会牺牲分布式的Failover特性,即只要有一台Broker不可用,整个集群都不可用。可以在Master Broker重启时自动将Slave切换为Master,即可在一定程度上避免顺序性被破坏,但也不能完全保证顺序性。
(13)队列:在RocketMQ中,所有消息队列都是持久化,长度无限的数据结构,所谓长度无限是指队列中的每个存储单元都是定长,访问其中的存储单元使用Offset来访问,offset为java long类型,64位,理论上在100年内不会溢出,所以认为是长度无限,另外队列中只保存最近几天的数据,之前的数据会按照过期时间来删除。

1.6 RocketMQ物理部署结构

RocketMQ基础知识点_第2张图片
(1)Name Server是一个几乎无状态节点,可集群部署,节点之间无任何信息同步。
(2)Broker部署相对复杂,Broker分为Master与Slave,一个Master可以对应多个Slave,但是一个Slave只能对应一个Master,Master与Slave的对应关系通过指定相同的BrokerName和不同的BrokerId来定义,BrokerId为0 表示Master,非0表示Slave。Master也可以部署多个。每个Broker与Name Server集群中的所有节点建立长连接,定时注册Topic信息到所有Name Server。
(3)Producer与Name Server集群中的其中一个节点(随机选择)建立长连接,定期从Name Server获取Topic路由信息,并向提供Topic服务的Master建立长连接,且定时向Master发送心跳。Producer完全无状态,可集群部署。
(4)Consumer与Name Server集群中的其中一个节点(随机选择)建立长连接,定期从Name Server获取Topic路由信息,并向提供Topic服务的Master、Slave建立长连接,且定时向Master、Slave发送心跳。

1.7 RocketMQ逻辑部署结构

RocketMQ基础知识点_第3张图片
Producer Group用来表示一个发送消息的应用,一个Producer Group下包含多个Producer 实例,可以是多台机器,也可以是一台机器的多个进程,或者一个进程的多个Producer对象。一个Producer Group可以发送多个Topic消息,Producer Group作用如下:
(1)标识一类Producer
(2)可以通过运维工具查询这个发送消息应用下有多个Producer实例
(3)发送分布式事务消息(后文有详细介绍事务消息)时,如果Producer中途意外宕机,Broker会主动回调Producer Group内的任意一台机器来确认事务状态。
Consumer Group用来表示一个消费消息的应用,一个Consumer Group下包含多个Consumer实例,可以是多台机器,也可以是多个进程,或者是一个进程的多个Consumer对象。一个Consumer Group下的多个Consumer以均摊方式消费消息。如果设置为广播方式,那么这个Consumer Group下的每个实例都消费全量数据。

2、RocketMQ设计原理

2.1 服务端架构

RocketMQ基础知识点_第4张图片
(1)Authorization & Authentication:授权认证
(2)Codec:编译码器
(3)Health Checker:健康检查
(4)Traffic Throttling & Circuit Breaker:限流和熔断机制
(5)Cache:缓存
(6)Mix Storage:混合存储
(7)VM Container:基于容器部署

2.2 客户端架构

RocketMQ基础知识点_第5张图片
(1)Broker Discovery:服务发现
(2)Keep Alive:长链接保持
(3)Traffic Throttling & Circuit Breaker:限流和熔断机制
(4)Retry:重试机制
(5)Meta-Info Notification:元信息发现
(6)VM Container:基于容器部署

2.3 数据模型

RocketMQ基础知识点_第6张图片
(1)一个Topic可以包含多条Message,但是每条Message仅拥有一个Topic。
(2)一个Topic可以包含多个Group(生产者或消费者分组),一个Group也可以包含多个Topic。
(3)一个Topic可以包含多个ConsumeQueue,但一个ConsumeQueue仅拥有一个Topic。

你可能感兴趣的:(java-rocketmq,rocketmq,java)