Consumer发起请求到Broker
有一个请求,那 Broker 必然会有一个processor初始化后的 Handler 来专门处理它,拉取消息对应的 RequestCode 是 PULL_MESSAGE,顾名思义就是拉取 Message
Broker进行校验
权限验证
参数验证
核心逻辑处理
通过MessageStore获取数据
MessageStore,即 Broker 对消息存储的封装。
传参:
consumergroup、topic、messagequeue、
offset、maxMsgNums、filter
简单翻译一下:
从指定 Topic MessageQueue 中查询 Message,
查询条数由 maxMsgNums 控制,
查询的起始偏移量由 offset 控制,
最后结果将通过 MessageFilter 进一步筛选,
这里其实就是根据 Message 的 Tag 对消息进行过滤。而像 maxMsgNums 和 offset 这些控制变量全部都由 Consumer 传给 Broker。
offset逻辑偏移量
queueOffset 就是逻辑偏移量。大家可以简单地理解为某个 MessageQueue 当中所存储的 Message 数量。
由Consumer发起请求时已经确定,原理是远程请求Broker查询
从远端 Broker 获取 Offset
此请求对应的 RequestCode 为 QUERY_CONSUMER_OFFSET
请求中会包含 3 个参数,分别是:ConsumerGroup、topic、QueueId。
在 ConsumerOffsetManager 的内部有一个叫 offsetTable 的 Map 来实际存储数据,Map 的详情如下。
Key:${Topic}@${ConsumerGroup} 的组合,即某个 Topic 下的某个消费者组。
Value:还是个 Map,也就是上图中右侧的部分。里面分别记录了 Consumer 在每个 MessageQueue 当中的消费进度。
最后一步
从 MessageStore 获取 Message
这里会通过传入的 Topic 和 MessageQueueID,找到其对应的 ConsumeQueue 索引
举个例子,假设我们要消费某个 MessageQueue 中的第 2 条消息,那么此时 RequestHeader 中的 Offset 值就是 1,那么 Broker 会根据 Offset 计算出其在 ConsumeQueue 文件中起始偏移量,即 1 * 20 = 20 ,每条 ConsumeQueue 大小固定为 20 字节,所以通过偏移量 + 消息长度就能够快速地定位到 ConsumeQueue。
定位到了 ConsumeQueue 就能够通过其中存储的物理偏移量 + 消息体长度快速定位到存储在磁盘上的 Message,还能通过 Tag 来进行消息过滤。