3.4.2 消费者迭代消费消息

3.4.2 消费者迭代消费消息

消费者迭代器生成包含消息的迭代器,首先弹出队列的每个数据块,然后获取数据块对应的消息
集,最后迭代消息集中的每条消息。客户端迭代的消息是队列的所有数据块,而不是一个数据块。所
以在迭代过程中,要确保读取完一个数据块后,接着读取下一个数据块。也就是说,消费者迭代器是:
所有数据块通过消息集f!fi成的消息迭代器。下面的伪代码实际上用了两层循环:

在这里插入图片描述

消费者迭代器实现了Java的Iterator接口,必须重载hasNext()和next()方法。hasNext()方法会用来判断迭代器是杏结束,next()方法每调用一次就指向迭代器的下一个元素。迭代的过程因为最上层数据结构是包含数据块的阻塞队列,所以从队列中弹出一个数据块就已经足够调用很多次next()了。只有当前数据块的消息集都遍历完成后,才会从队列中弹出新的数据块。相关代码如下:

在这里插入图片描述

注意:在迭代的过程中,可能多次调用next()方法都还是在同一数据块的同一个消息集中,所以迭代器妥保存当前的数据块(currentDataChunk变量)、当前的消息集(current机』rrentMessageSet变量)。如果当前消息集没有下一个元素,则需要同时更新这两个变量。因为一个数据块对应一个消息集,一旦当前消息集没有元素了,说明这个数据块也.已经迭代完毕。

消费者的“拉取线程”拉取消息后会更新“拉取状态”,对应的“消费线程”获取消息后也要更新相关的“消费状态”。(准确地说,消费消息的对象是一个迭代器而不是钱程。这里为了和拉取线程相对应,故叫作消费线程。)拉取状态对应分区信息、对象的拉取偏移量(fetchedOffset),表示消费者已经拉取的分区位置;消费状态对应了消费偏移量(consumedOffset),表示消费者已经消费完成的偏移量。

如图3-23所示,拉取消息的线程和消费消息的线程是两个独立的工作模块,前者通过分区信息对象的阻塞队列将消息传给消费消息的线程完成数据的传输。消息拉取后只有被消费线程真正消费后,才会更新消费状态。也就是说,“拉取线程更新拉取偏移量,消费线程更新消费偏移量”,具体步骤如下。

(1)消费者的拉取线程从服务端拉取分区的消息。
(2)拉取到分区消息后,就更新分区信息对象的拉取偏移量。
(3)将分区数据的消息集封装成数据块。
(4)客户端循环迭代数据块的消息集。
(5)消费完一条消息后,就更新分区信息对象的消费偏移量。
(6)消息流中的每一条消息返回给消费者客户端应用程序。

在这里插入图片描述

分区信息的拉取偏移i1l初始时从ZK读取,然后在拉取消息后更新。同样,消费偏移盘初始时也是从ZK读取,然后在消费消息后更新。消费者消费了新的消息后,还应该及时地将消费进度(即分区信息的消费偏移盘)保存到ZK中。

相关推荐
©️2020 CSDN 皮肤主题: 酷酷鲨 设计师:CSDN官方博客 返回首页