【RocketMQ】RocketMQ 5.0新特性(二)- Pop消费模式

rocketmq,特性,pop,消费,模式 · 浏览次数 : 31

小编点评

**Pop 模式消费和消息粒度负载均衡** **Pop 模式** 1. 消费者向服务端发送 Pop 请求,请求获取消息。 2. 服务端以 Pop 模式获取消息,并返回给消费者。 3. 消费者消费消息成功后,向服务端发送 ACK 请求确认消息消费成功。 4. 服务端根据 ACK 消息,从队列中获取并构建 CheckPoint 信息。 5. CheckPoint 包含消息的 Topic、ConsumerGroup、QueueId、offset、POPTime、msgCout、reviveQueueId 等信息。 **消息粒度负载均衡** 1. 服务端根据消息队列数量和消费者数量设置消息粒度。 2. 当消费者获取到消息后,服务端会对该消息加锁,保证该消息只被一个消费者消费。 3. 服务端从队列中获取一批消息,并构建这批消息对应的 CheckPoint 信息保存在 Broker 中。 4. CheckPoint 包含消息的 Topic、ConsumerGroup、QueueId、offset、POPTime、msgCout、reviveQueueId 等信息。 5. CheckPoint 会优先保存在内存中,如果在一段时间内收到了客户端的 ACK 消息,就会将对应的 CheckPoint 清除,并更新消费进度。 **结论** Pop 模式消费和消息粒度负载均衡是 RocketMQ 5.0 中两种可选的消费模式。Pop 模式适用于单线程消费,消息粒度负载均衡适用于多线程消费。

正文

Pop模式消费和消息粒度负载均衡

在RocketMQ 5.0之前,消费有两种方式可以从Broker获取消息,分别为Pull模式和Push模式。

  • Pull模式:消费需要不断的从阻塞队列中获取数据,如果没有数据就等待,这个阻塞队列中的数据由消息拉取线程从Broker拉取消息之后加入的,所以Pull模式下消费需要不断主动从Broker拉取消息。
  • Push模式:需要注册消息监听器,当有消息到达时会通过回调函数进行消息消费,从表面上看就像是Broker主动推送给消费者一样,所以叫做推模式,底层依旧是消费者从Broker拉取数据然后触发回调函数进行消息消费,只不过不需要像Pull模式一样不断判断是否有消息到来。


注:图片来自RocketMQ官方文档

不过不管是Pull模式还是Push模式,在集群模式下,一个消息队列只能分配给同一个消费组内的某一个消费者进行消费,所以需要进行Rebalance负载均衡为每个消费者分配消息队列之后才可以进行消息消费。
Rebalance的工作是在每个消费者端进行的,消费端负责的工作太多,除了负载均衡还有消费位点管理等功能,如果新增一种语言的支持,就需要重新实现一遍对应的业务逻辑代码。

除此以外,在RocketMQ 5.0以前负载均衡是以消息队列为维度为每个消费者分配的,一个消息队列只能分给组内一个消费者消费,所以会存在以下问题:

(1)队列只能分给组内一个消费者消费,也就无法通过扩展消费者的数量来提升消费能力;
(2)消息队列数量与消费者数量比例不均衡时,可能会导致某些消费者没有消息队列可以分配或者某些消费者承担过多的消息队列,分配不均匀;
(3)如果某个消费者hang主,会导致分配到该消费者的消息队列中的消息无法消费,导致消息积压;

在RocketMQ 5.0增加了Pop模式消费,将负载均衡、消费位点管理等功能放到了Broker端,减少客户端的负担,使其变得轻量级,并且5.0之后支持消息粒度的负载均衡。

消息粒度负载均衡

对于PushConsumer和SimpleConsumer类型的消费者,默认且仅使用消息粒度负载均衡策略。

注:图片来自RocketMQ官方文档

消息粒度负载均衡策略中,同一消费组内的多个消费者将按照消息粒度平均分摊主题中的所有消息,即同一个队列中的消息,可被平均分配给组内多个消费者共同消费。

消息粒度负载均衡策略保证同一个队列的消息可以被组内多个消费者共同处理,但是该策略使用的消息分配算法结果是随机的,不能指定消息被哪一个特定的消费者处理。当消费者获取到某条消息后,服务端会对该消息加锁,保证该消息对其他消费者不可见,直到消息消费成功或者超时,所以多个消费者同时消费同一个消息队列中的消息,服务端也可以保证消息不会被多个消费者重复消费。

消息粒度负载均衡策略适用于绝大多数在线处理的业务场景。

Pop消息消费

首先客户端(消费者)向服务端(Broker)发送Pop请求,Broker端收到请求后以Pop模式获取消息,之后返回给客户端,客户端消费消息成功之后,向Broker发送ACK请求确认消息消费成功。

当POP出一条消息之后,这条消息就会在一段时间内不可见,在这个时间段内,这条消息不会再被POP出来,如果在这个期间未能收到该消息的ACK请求,过了这个不可见的时间之后,消息就会恢复可见状态,重新被消费。

POP的消费位点由Broker保存和控制,并且POP模式可以使多个消费者端消费同一个消息队列中的消息,消费者端不再需要在本地做负载均衡分配消息队列,只需要调用服务端提供的POP接口获取消息进行消费即可,即便某个消费者hang住,其他消费者依旧可以继续消费队列中的数据,不会造成消息堆积。

POP消息在Broker端的实现

  1. Broker端在处理POP请求时,先在队列维度加锁,保证同一时间只有一个消费者可以从该队列中获取消息;

  2. Broker端会从队列中获取一批消息,并构建这批消息对应的CheckPoint信息保存在Broker中,之后会与ACK的消息进行匹配;
    CheckPoint主要包括消息的 Topic,ConsumerGroup,QueueId,offset,POPTime,msgCout,reviveQueueId等信息。

  3. CheckPoint会优先保存在内存中,如果在一段时间内收到了客户端的ACK消息,就会将对应的CheckPoint清除,并更新消费进度;

  4. 对于一段时间内为收到ACK消息的CheckPoint,会将其从内存中删除,然后发送到延时主题SCHEDULE_TOPIC_XXXX中,到达延时时间之后,消息会再被转发到REVIVE_TOPIC(会使用REVIVE_LOG_ + 集群名称作为主题)中,有一个线程去处理REVIVE_TOPIC中的数据,将里面的消息拉取放入到一个
    MAP中,如果后续收到对应的ACK消息,则会更新REVIVE_TOPIC主题中的消费位点标识消息消费完成,如果过了一定时间依旧未收到对应的ACK消息,会查找这个CheckPoint对应的真实消息,将其放入到重试队列中,等待客户端消费,所以消费者消费的时候有一定概率可以消费到重试队列中的消息。

由于一个消息队列中的消息可以被多个消费者消费,如果某个消费者在消费某条消息之后一直未发生ACK消息,那么Broker是如何管理消费进度的,比如队列1中有1、2、3、4、5条消息,此时有三个消费者1、2、3,分别分配到了队列中的1、2、3条消息,此时消费者1已经对消息1ACK完毕,消费者3也对消息3ACK完毕,消费者2一直未ACK消息2,那么Broker如何设置消费进度?

个人认为,在一段时间内消息2对应的CheckPoint未匹配到对应的ACK消息,为了保证消费可以继续向后消费消息,应该会推进消费进度跳过这个消息,对于消息2,会按照超时处理逻辑,将其对应的CheckPoint先放入延时队列,再放入REVIVE_TOPIC中,之后等待ACK,如果之后一直还未收到ACK再将其放入重试队列,等待重新消费。

参考
RocketMQ官方文档

RocketMQ 5.0 POP 消费模式探秘

与【RocketMQ】RocketMQ 5.0新特性(二)- Pop消费模式相似的内容:

【RocketMQ】RocketMQ 5.0新特性(二)- Pop消费模式

Pop模式消费和消息粒度负载均衡 在RocketMQ 5.0之前,消费有两种方式可以从Broker获取消息,分别为Pull模式和Push模式。 Pull模式:消费需要不断的从阻塞队列中获取数据,如果没有数据就等待,这个阻塞队列中的数据由消息拉取线程从Broker拉取消息之后加入的,所以Pull模式下

【RcoketMQ】RcoketMQ 5.0新特性(一)- Proxy

为了向云原生演进,提高资源利用和弹性能力,RcoketMQ在5.0进行了架构的调整与升级,先来看新特性之一,增加了Proxy层。 增加Proxy代理层 计算存储分离 计算存储分离是一种分层架构,将计算层与存储层分开。 计算层指的是一些消耗计算资源的功能模块比如协议解析、消费管理等,存储指的是数据存储

RocketMQ 事件驱动:云时代的事件驱动有啥不同?

本文深入探讨了云时代 EDA 的新内涵及它在云时代再次流行的主要驱动力,包括技术驱动力和商业驱动力,随后重点介绍了 RocketMQ 5.0 推出的子产品 EventBridge,并通过几个云时代事件驱动的典型案例,进一步叙述了云时代事件驱动的常见场景和最佳实践。

[转帖]Kafka 与RocketMQ 落盘机制比较

https://www.jianshu.com/p/fd50befccfdd 引言 前几期的评测中,我们对比了Kafka和RocketMQ的吞吐量和稳定性,本期我们要引入一个新的评测标准——软件可靠性。 何为“可靠性”? 先看下面这种情况:有A,B两辆越野汽车,在城市的周边地区均能很好应对泥泞的路况

RocketMQ 之 IoT 消息解析:物联网需要什么样的消息技术?

前言: 从初代开源消息队列崛起,到 PC 互联网、移动互联网爆发式发展,再到如今 IoT、云计算、云原生引领了新的技术趋势,消息中间件的发展已经走过了 30 多个年头。 目前,消息中间件在国内许多行业的关键应用中扮演着至关重要的角色。随着数字化转型的深入,客户在使用消息技术的过程中往往同时涉及交叉场

[转帖]RocketMQ - nameSrv和Broker

RocketMQ RocketMQ是一个统一的消息传递引擎,轻量级的数据处理平台。 Name Server Name Server充当路由消息的提供者,生产者(Producer)或消费者(Customer)可以通过Name Server查找各主题对应的Broker IP列表,多个Name Serve

【主流技术】聊一聊消息队列 RocketMQ 的基本结构与概念

RocketMQ 是阿里巴巴在 2012 年开源的分布式消息中间件,目前已经捐赠给 Apache 软件基金会,并于 2017 年 9 月 25 日成为 Apache 的顶级项目。 作为经历过多次阿里巴巴双十一这种“超级工程”的洗礼并有稳定出色表现的国产中间件,以其高性能、低延时和高可靠等特性近年来...

RocketMq开启安全认证ACL-解决服务器系统安全漏洞

1、为什么要开启ACL 通过之前的文章我们已经知道怎么安装RocketMq了。如果你还不会安装RocketMq可以查看我的这篇文章:快速入门一篇搞定RocketMq-实现微服务实战落地 进行软件安装,附文章地址:https://www.cnblogs.com/sowler/p/18173752 。虽

如何实现一个简单易用的 RocketMQ SDK

2018 年,做为架构负责人,接到一个架构需求:实现一个简单易用的 RocketMQ SDK 。 因为各个团队 RocketMQ 原生客户端配置起来千奇百怪,有的配置存在风险,各团队负责人都需要一个简洁易用的 RocketMQ SDK 。 我立马调研相关开源的方案,当时 RocketMQ-Sprin

【RocketMQ】顺序消息实现总结

全局有序 在RocketMQ中,如果使消息全局有序,可以为Topic设置一个消息队列,使用一个生产者单线程发送数据,消费者端也使用单线程进行消费,从而保证消息的全局有序,但是这种方式效率低,一般不使用。 局部有序 假设一个Topic分配了两个消息队列,生产者在发送消息的时候,可以对消息设置一个路由I