概述
这篇文章的目的主要是为了讲清楚rocketMq消息堆积的概念,我印象中的rocketMq的消息堆积应该分为两层,一层是broker中实际写入消息量和consumeQueue已经消费位移的偏差,另外一层consumer端本身已经拉取消息的堆积,而今天要讲的正是后者。
这个问题的起源是当时有个其他公司的同事遇到consumer端不停的gc,然后开始谈论起这个话题,然后我就按照我的理解给他解释了一遍,结果发现的确是那么回事,所以才有了这篇记录。我觉得我应该能够把整个过程讲清楚。
PS,这个是在rocketMq的push模式下才会遇到的情况,pull场景下由于自行控制拉取速度,所以不太可能出这个问题。
push消费模式
1、push消费模式本质上其实一个pull的过程,consumer本质上在执行两个阶段的任务,阶段一是负责从broker端pull消息到consumer端,阶段二负责将拉取的消息push到consumer注册的回调当中。
2、阶段一的pull过程需要其实是一个多个维度的过程,假设我们的broker集群包含3个broker节点,在这个集群上我们创建了一个topic并且topic指定的队列个数为6,那么在这个场景下我们总共有3*6=18个队列,其中3是3个broker,6是每个topic的队列数。
3、在步骤2的基础上,假设我们的consumerGroup只有一个consumer,那么这个consumer就需要负责消费18个队列。
4、由于每个queue的拉取都是由单独任务在驱动的,所以总共有18个拉取任务,由一个线程的串行进行拉取,拉取完后再次重复提交进行二次拉取过程,循环往复持续拉取数据。
5、拉取过程中如果发现消息数据条数超过1000条,或者消息量超过100M,那么我们就暂停消息拉取,延迟50ms后再次发起任务拉取。
push模式下消息堆积
1、在18个队列的模式下,假设我们的consumer消费非常慢的话,理论上我们能够堆积100M*18=1800M=1.8G,假设这个consumer同时订阅多个topic的话,假设3个topic,那么就会超过1.8G*3=5.4G。在这种情况下很容易发生gc。