概述
这篇文章的目的主要是为了讲清楚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。
push模式下代码分析
![img_09c1371abc5e70e586f5d4d08f4c3e57.png](https://i-blog.csdnimg.cn/blog_migrate/ce2db66e9d0ea188a31c9484a0cca9e6.png)
![img_e4ce52f643dc8d517e526346871b9fbb.png](https://i-blog.csdnimg.cn/blog_migrate/4829ea32b3f91da594b1d7b28b821997.png)
![img_935a8a827d5f9571b6ab51927d332bd6.png](https://i-blog.csdnimg.cn/blog_migrate/8205b0956a884525a18d6ed2941e221d.png)
![img_6e065d70179abdf0ac78b5e2f4a2b513.png](https://i-blog.csdnimg.cn/blog_migrate/df2fa9e2f28625d4f789e3be638b9255.png)
![img_da9f75f8acf93ebb214cbf508d4dfd16.png](https://i-blog.csdnimg.cn/blog_migrate/ab7de86684d26e86961c156b57ea08ac.png)
![img_0cbb940ce5781ca4aa8d551d757cfd68.png](https://i-blog.csdnimg.cn/blog_migrate/9b8fd851cd4ec44166278197188a973e.png)