=================
== Time Stream ==
=================
一个小学生

RocketMQ中的消息消费

RocketMQ

RocketMQ的消息消费学习。

一个消费组内可以包含多个消费者,每个消费组可订阅多个Topic。消费组之间有集群模式和广播模式:

  • 集群模式,Topic下的同一条消息只允许被其中一个消费者消费。
  • 广播模式,Topic下的同一条消息被集群内所有消费者消费一次。

消息服务器与消费者之间的消息传送有推模式和拉模式:

  • 拉模式,消费者主动发起拉消息的请求
  • 推模式,消息到达消息服务器后,推送给消息消费者,RocketMQ的推模式基于拉模式,在拉模式上包装一层,一个拉取任务完成后开始下一个拉取任务

一个消息队列同一时间只允许被一个消费者消费,一个消费者可以消费多个消息队列。

RocketMQ支持局部顺序消息消费,保证同一消息队列上的消息顺序消费。不支持全局顺序消费,如果要实现某个Topic的全局顺序消费,可将该Topic的队列设置为1,牺牲了高可用性。

消费者启动流程

  • 构建主题订阅信息SubscriptionData并加入到RebalanceImpl订阅消息中,订阅信息主要有通过subscribe方法订阅,订阅重试主题消息。
  • 初始化MQClientInstance、RebalanceImpl等
  • 初始化消息进度,集群模式的消息进度存储在Broker上,广播模式的消费进度存储在消费端。
  • 根据是否是顺序消费,创建消费端消费线程服务。
  • 向MQClientInstance注册消费者,并启动MQClientInstance,MQClientInstance在一个JVM只存在一个实例。

消息拉取

  • 封装拉取消息的请求
  • 消息服务器查找消息,返回
  • 客户端处理拉取到的消息

消息队列负载和重新分布机制

消息队列重新分布是由RebalanceService线程来实现,每隔20s执行一次doRebalance方法。

RocketMQ默认提供5中分分配算法:

  • 平均分配,如果有8个消费队列q1,q2,q3,q4,q5,q6,q7,q8,有三个消费者c1,c2,c3,则消息队列分配如下:c1对应q1,q2,q3;c2对应q4,q5,q6;c3对应q8
  • 平均轮询分配,消息队列分配如下:c1对应q1,q4,q7;c2对应q2,q5,q8;c3对应q3,q6
  • 一致性哈希,不推荐,消息队列负载信息不容易跟踪
  • 根据配置,为每个消费者配置固定的消息队列
  • 根据Broker部署机房名,对每个消费者负责不同的Broker上的队列