天天看點

rocketMq的消息堆積

概述

    這篇文章的目的主要是為了講清楚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模式下代碼分析

rocketMq的消息堆積

push-pull-1

rocketMq的消息堆積

push-pull-2

rocketMq的消息堆積

push-pull-3

rocketMq的消息堆積

push-pull-4

rocketMq的消息堆積

push-pull-5

rocketMq的消息堆積

push-pull-6