RocketMQ---功能特性
消息分类
普通消息
https://rocketmq.apache.org/zh/docs/featureBehavior/01normalmessage
普通消息为 Apache RocketMQ 中最基础的消息;
应用场景
应用于微服务解耦、事件驱动、数据集成等场景,这些场景大多数 要求 数据传输通道具有可靠传输的能力,且对消息的处理时机、处理顺序没有特别要求;
微服务异步解耦
功能原理
定义
普通消息是Apache RocketMQ基本消息功能,支持生产者和消费者的异步解耦通信。
生命周期
-
初始化:消息被生产者构建并完成初始化,待发送到服务端的状态。
-
待消费:消息被发送到服务端,对消费者可见,等待消费者消费的状态。
-
消费中:消息被消费者获取,并按照消费者本地的业务逻辑进行处理的过程。 此时服务端会等待消费者完成消费并提交消费结果,如果一定时间后没有收到消费者的响应,Apache RocketMQ会对消息进行重试处理。具体信息,请参见消费重试。
-
消费提交:消费者完成消费处理,并向服务端提交消费结果,服务端标记当前消息已经被处理(包括消费成功和失败)。 Apache RocketMQ默认支持保留所有消息,此时消息数据并不会立即被删除,只是逻辑标记已消费。消息在保存时间到期或存储空间不足被删除前,消费者仍然可以回溯消息重新消费。
-
消息删除:Apache RocketMQ按照消息保存机制滚动清理最早的消息数据,将消息从物理文件中删除。更多信息,请参见消息存储和清理机制。
使用限制
仅支持使用MessageType为Normal主题,即普通消息只能发送至类型为普通消息的主题中,发送的消息的类型必须和主题的类型一致;
定时/延时消息
https://rocketmq.apache.org/zh/docs/featureBehavior/02delaymessage
定时/延时消息为 Apache RocketMQ 中的高级特性消息;
定时消息和延时消息本质相同,都是 服务端 根据消息设置的定时时间在某一固定时刻将消息投递给消费者消费。因此,下文统一用定时消息描述。
应用场景
在分布式 定时调度触发、任务超时处理等场景,需要实现精准、可靠的定时事件触发。
使用 Apache RocketMQ 的定时消息可以简化定时调度任务的开发逻辑,实现高性能、可扩展、高可靠的定时触发能力。
分布式定时调度
任务超时处理
功能原理
定义
定时消息是 Apache RocketMQ 提供的一种高级消息类型,消息被发送至服务端后,在指定时间后才能被消费者消费。
通过 设置一定的定时时间 可以实现 分布式场景的延时调度触发效果;
生命周期
-
初始化:消息被生产者构建并完成初始化,待发送到服务端的状态。
-
定时中:消息被发送到服务端,和普通消息不同的是,服务端不会直接构建消息索引,而是会将定时消息单独存储在定时存储系统中,等待定时时刻到达。
-
待消费:定时时刻到达后,服务端将消息重新写入普通存储引擎,对下游消费者可见,等待消费者消费的状态。
-
消费中:消息被消费者获取,并按照消费者本地的业务逻辑进行处理的过程。 此时服务端会等待消费者完成消费并提交消费结果,如果一定时间后没有收到消费者的响应,Apache RocketMQ会对消息进行重试处理。具体信息,请参见消费重试。
-
消费提交:消费者完成消费处理,并向服务端提交消费结果,服务端标记当前消息已经被处理(包括消费成功和失败)。 Apache RocketMQ 默认支持保留所有消息,此时消息数据并不会立即被删除,只是逻辑标记已消费。消息在保存时间到期或存储空间不足被删除前,消费者仍然可以回溯消息重新消费。
-
消息删除:Apache RocketMQ按照消息保存机制滚动清理最早的消息数据,将消息从物理文件中删除。更多信息,请参见消息存储和清理机制。
使用限制
消息类型一致性
定时消息仅支持在 MessageType为Delay 的主题内使用,即定时消息只能发送至类型为定时消息的主题中,发送的消息的类型必须和主题的类型一致。
定时精度约束
Apache RocketMQ 定时消息的定时时长参数精确到毫秒级,但是默认精度为1000ms,即定时消息为秒级精度。
Apache RocketMQ 定时消息的状态支持持久化存储,系统由于故障重启后,仍支持按照原来设置的定时时间触发消息投递。若存储系统异常重启,可能会导致定时消息投递出现一定延迟。
顺序消息
https://rocketmq.apache.org/zh/docs/featureBehavior/03fifomessage
顺序消息为 Apache RocketMQ 中的高级特性消息;
应用场景
在有序事件处理、撮合交易、数据实时增量同步等场景下,异构系统间需要维持强一致的状态同步,上游的事件变更需要按照顺序传递到下游进行处理。
在这类场景下使用 Apache RocketMQ 的顺序消息可以有效保证数据传输的顺序性。
功能原理
什么是顺序消息
顺序消息是 Apache RocketMQ 提供的一种高级消息类型,支持 消费者 按照发送消息的先后顺序获取消息,从而实现业务场景中的顺序处理。 相比其他类型消息,顺序消息在发送、存储和投递的处理过程中,更多强调多条消息间的先后顺序关系。
Apache RocketMQ 顺序消息的顺序关系 通过消息组(MessageGroup)判定和识别, 发送顺序消息时需要为每条消息设置归属的消息组,相同消息组 的多条消息之间 遵循先进先出的顺序关系,不同消息组、无消息组的消息之间不涉及顺序性。
基于消息组的顺序判定逻辑,支持按照业务逻辑做细粒度拆分,可以在满足业务局部顺序的前提下提高系统的并行度和吞吐能力。
如何保证消息的顺序性
生产顺序性:
通过生产者和服务端的协议保障单个生产者串行地发送消息,并按序存储和持久化;
单一生产者 && 串行发送;
消费顺序性:
通过消费者和服务端的协议保障消息消费严格按照存储的先后顺序来处理。
事务消息
事务消息为 Apache RocketMQ 中的高级特性消息;
https://rocketmq.apache.org/zh/docs/featureBehavior/04transactionmessage
应用场景
分布式事务
功能原理
保证 本地事务(3)与消息生产(4) 的 最终一致性
什么是事务消息
事务消息是 Apache RocketMQ 提供的一种高级消息类型,支持 在分布式场景下 保障 消息生产和本地事务的最终一致性;
消息发送重试和流控机制
https://rocketmq.apache.org/zh/docs/featureBehavior/05sendretrypolicy
消息发送重试机制
重试基本概念
Apache RocketMQ 客户端连接服务端发起消息发送请求时,可能会因为网络故障、服务异常等原因导致调用失败。
为保证消息的可靠性, Apache RocketMQ 在客户端SDK中内置请求重试逻辑,尝试通过重试发送达到最终调用成功的效果。
同步发送和异步发送模式均支持消息发送重试。
重试流程
生产者在初始化时设置消息发送最大重试次数,当出现上述触发条件的场景时,生产者客户端会按照设置的重试次数一直重试发送消息,直到消息发送成功或达到最大重试次数重试结束,并在最后一次重试失败后返回调用错误响应。
-
同步发送:调用线程会一直阻塞,直到某次重试成功或最终重试失败,抛出错误码和异常。
-
异步发送:调用线程不会阻塞,但调用结果会通过异常事件或者成功事件返回。
消息流控机制
消息流控基本概念
消息流控指的是系统容量或水位过高, Apache RocketMQ 服务端会通过快速失败返回流控错误来避免底层资源承受过高压力。
消费者分类
https://rocketmq.apache.org/zh/docs/featureBehavior/06consumertype
Apache RocketMQ 支持 PushConsumer 、 SimpleConsumer 以及 PullConsumer 这三种类型的消费者,本文分别从使用方式、实现原理、可靠性重试和适用场景等方面为您介绍这三种类型的消费者;
Apache RocketMQ 面向不同的业务场景 提供了不同消费者类型,每种消费者类型的集成方式和控制方式都不一样。了解如下问题,可以帮助您选择更匹配业务场景的消费者类型。
-
如何实现并发消费:消费者如何使用并发的多线程机制处理消息,以此提高消息处理效率?
-
如何实现同步、异步消息处理:对于不同的集成场景,消费者获取消息后可能会将消息异步分发到业务逻辑中处理,此时,消息异步化处理如何实现?
-
如何实现消息可靠处理:消费者处理消息时如何返回响应结果?如何在消息异常情况进行重试,保证消息的可靠处理?
在实际使用场景中,PullConsumer 仅推荐在流处理框架中集成使用,大多数消息收发场景使用 PushConsumer 和 SimpleConsumer 就可以满足需求。
PushConsumer
PushConsumers是一种高度封装的消费者类型,消费消息 仅通过消费监听器 处理业务并返回消费结果。消息的获取、消费状态提交以及消费重试都通过 Apache RocketMQ 的客户端SDK完成;
消息过滤
https://rocketmq.apache.org/zh/docs/featureBehavior/07messagefilter
消费者 订阅了某个主题后,Apache RocketMQ 会将该主题中的所有消息投递给消费者。
若消费者只需要关注部分消息,可通过设置过滤条件在 Apache RocketMQ 服务端进行过滤,只获取到需要关注的消息子集,避免接收到大量无效的消息;
应用场景
解决的单个业务域即 同一个主题 内 不同消息子集的过滤问题,一般是基于同一业务下更具体的分类进行过滤匹配。如果是需要对不同业务域的消息进行拆分,建议使用不同主题处理不同业务域的消息;
功能概述
消息过滤主要通过以下几个关键流程实现:
-
生产者:在初始化消息时 预先为消息设置一些属性和标签,用于后续消费时指定过滤目标。
-
消费者:在初始化及后续消费流程中通过调用订阅关系注册接口,向服务端上报需要订阅指定主题的哪些消息,即过滤条件。
-
服务端:消费者获取消息时 会触发服务端的动态过滤计算,Apache RocketMQ 服务端根据消费者上报的过滤条件的表达式进行匹配,并将符合条件的消息投递给消费者。
tag标签过滤
Tag标签过滤方式是 Apache RocketMQ 提供的基础消息过滤能力,基于 生产者为消息设置的Tag标签进行匹配。
生产者在发送消息时,设置消息的Tag标签,消费者需指定已有的Tag标签来进行匹配订阅;
SQL属性过滤
SQL属性过滤是 Apache RocketMQ 提供的高级消息过滤方式,通过 生产者为消息设置的属性(Key)及属性值(Value)进行匹配。
生产者在发送消息时可设置多个属性,消费者订阅时可设置SQL语法的过滤表达式过滤多个属性;
消费者负载均衡
https://rocketmq.apache.org/zh/docs/featureBehavior/08consumerloadbalance
消费者 从 Apache RocketMQ 获取消息消费时,通过消费者负载均衡策略,可将 主题内的消息 分配给 指定消费者分组中的多个消费者 共同分担,提高 消费并发能力 和 消费者的水平扩展能力;
解决的问题
-
消息消费处理的容灾策略:您可以根据消费者负载均衡策略,明确当局部节点出现故障时,消息如何进行消费重试和容灾切换。
-
消息消费的顺序性机制:通过消费者负载均衡策略,您可以进一步了解消息消费时,如何保证同一消息组内消息的先后顺序。
-
消息分配的水平拆分策略:了解消费者负载均衡策略,您可以明确消息消费压力如何被分配到不同节点,有针对性地进行流量迁移和水平扩缩容。
消费方式
-
消费组间广播消费 :如上图所示,每个消费者分组 只初始化唯一一个消费者,每个消费者可消费到消费者分组内所有的消息,各消费者分组都订阅相同的消息,以此实现单客户端级别的广播一对多推送效果。
该方式一般可用于 网关推送、配置推送 等场景。
-
消费组内共享消费 :如上图所示,每个消费者分组下 初始化了多个消费者,这些消费者共同分担消费者分组内的所有消息,实现消费者分组内流量的水平拆分和均衡负载。
该方式一般可用于 微服务解耦 场景。
消费者负载均衡
共享消费场景
(广播消费场景下,每个消费者分组内只有一个消费者,因此不涉及消费者的负载均衡)
根据消费者类型的不同,消费者负载均衡策略分为以下两种模式:
消息粒度负载均衡
使用范围
对于PushConsumer和SimpleConsumer类型的消费者,默认且仅使用消息粒度负载均衡策略。
策略原理
同一消费者分组内的 多个消费者 将按照消息粒度平均分摊主题中的所有消息(同一个队列中的消息,可被平均分配给多个消费者共同消费);
消息粒度负载均衡策略保证同一个队列的消息可以被多个消费者共同处理,但是该策略使用的消息分配算法结果是随机的,并不能指定消息被哪一个特定的消费者处理。
消息粒度的负载均衡机制,是基于内部的单条消息确认语义实现的。消费者获取某条消息后,服务端会将该消息加锁,保证这条消息对其他消费者不可见,直到该消息消费成功或消费超时。因此,即使多个消费者同时消费同一队列的消息,服务端也可保证消息不会被多个消费者重复消费;
顺序消息负载机制
在顺序消息中,消息的顺序性指的是同一消息组内的多个消息之间的先后顺序。
因此,顺序消息场景下,消息粒度负载均衡策略 还需要保证 同一消息组内的消息,按照服务端存储的先后顺序进行消费。不同消费者处理同一个消息组内的消息时,会严格按照先后顺序锁定消息状态,确保同一消息组的消息串行消费;
队列粒度负载均衡
使用范围
对于历史版本(服务端4.x/3.x版本)的消费者,包括PullConsumer、DefaultPushConsumer、DefaultPullConsumer、LitePullConsumer等,默认且仅能使用队列粒度负载均衡策略。
策略原理
同一消费者分组内的 多个消费者将 按照队列粒度消费消息(每个队列仅被一个消费者消费)。
版本兼容性
消费进度管理
https://rocketmq.apache.org/zh/docs/featureBehavior/09consumerprogress
Apache RocketMQ 通过消费位点管理消费进度;
消息位点(offset)
消息 按到达服务端的先后顺序 存储在指定主题的多个队列中,每条消息 在队列中都有一个唯一的Long类型坐标,这个坐标被定义为消息位点。
任意一个消息队列 在逻辑上都是无限存储,即消息位点会从0到Long.MAX无限增加;
通过主题、队列和位点就可以定位 任意一条消息的位置;
Apache RocketMQ 定义队列中最早一条消息的位点为最小消息位点(MinOffset);最新一条消息的位点为最大消息位点(MaxOffset)。
虽然消息队列 逻辑上是无限存储,但由于服务端物理节点的存储空间有限, Apache RocketMQ 会滚动删除队列中存储最早的消息。因此,消息的最小消费位点和最大消费位点会一直递增变化。
消费位点(ConsumerOffset)
Apache RocketMQ 领域模型为发布订阅模式,每个主题的队列都可以被多个消费者分组订阅。
每条消息 被某个消费者消费完成后 不会立即在队列中删除,Apache RocketMQ 会基于每个消费者分组 维护一份消费记录,该记录 指定 消费者分组 消费某一个队列时,消费过的最新一条消息的位点,即消费位点。
当消费者客户端离线,又再次重新上线时,会严格按照服务端保存的消费进度继续处理消息。
如果服务端保存的历史位点信息已过期被删除,此时消费位点向前移动至服务端存储的最小位点;
消费位点初始值
指的是 消费者分组 首次启动消费者消费消息时,服务端保存的消费位点的初始值;
Apache RocketMQ 定义消费位点的初始值为消费者首次获取消息时,该时刻队列中的最大消息位点。相当于消费者将从队列中最新的消息开始消费。
重置消费位点
若消费者分组的初始消费位点或当前消费位点不符合您的业务预期,您可以通过重置消费位点调整您的消费进度。
适用场景
-
初始消费位点不符合需求:因初始消费位点为当前队列的最大消息位点,即客户端会直接从最新消息开始消费。若业务上线时需要消费部分历史消息,您可以通过重置消费位点功能消费到指定时刻前的消息。
-
消费堆积快速清理:当下游消费系统性能不足或消费速度小于生产速度时,会产生大量堆积消息。若这部分堆积消息可以丢弃,您可以通过重置消费位点快速将消费位点更新到指定位置,绕过这部分堆积的消息,减少下游处理压力。
-
业务回溯,纠正处理:由于业务消费逻辑出现异常,消息被错误处理。若您希望重新消费这些已被处理的消息,可以通过重置消费位点快速将消费位点更新到历史指定位置,实现消费回溯。
使用建议
严格控制消费位点重置的权限
重置消费位点会给系统带来额外处理压力,可能会影响新消息的读写性能。 因此该操作请在适用场景下谨慎执行,并提前做好合理性和必要性评估。
消费重试
https://rocketmq.apache.org/zh/docs/featureBehavior/10consumerretrypolicy
消费者 出现异常,消费某条消息失败时, Apache RocketMQ 会根据 消费重试策略 重新投递该消息进行故障恢复;
消费重试策略概述
消费重试指的是,消费者在消费某条消息失败后,Apache RocketMQ 服务端会根据重试策略重新消费该消息,超过一次定数后若还未消费成功,则该消息将不再继续重试,直接被发送到死信队列中。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)
2022-03-11 Spring---Bean生命周期
2020-03-11 Mysql---docker部署主从同步