本文记录了和conumser相关的几个类。

首先是RequestFuture这个类,consumer和服务端通信使用它作为返回值。

其次是HeartBeat机制,consumer和coordinator通过它来获取对方的状态,并进行相应的处理。

然后是SubscriptionState,consumer消费topic的信息都保存在这个类中。

最后是Fetcher, 它负责从broker中拉取数据。

RequestFuture

RequestFuture 是ConsumerNetworkClient发出请求的异步返回值。当请求结果返回后,会对结果进行分析,并且遍历listeners处理请求结果。

这样子,就会有三个变量:

  1. Object 对象 INCOMPLETE_SENTINEL 表示 请求结果没有完成。
  2. AtomicReference result 表示结果的返回值。
  3. ConcurrentLinkedQueue<RequestFutureListener> listeners 表示一个监听者列表,对返回结果进行处理。
    1. RequestFutureListener 里面有 onSuccess 和 onFailure 方法分别用于处理成功和失败的请求。

RequestFuture有以下几个方法:

  1. isDone:future已经完成了,可以被后续handler处理。
  2. succeeded: future已经完成了,并且结果没有错误。
  3. failed: 查看返回结果有没有出错。
  4. isRetriable: 如果返回结果出错了,查看这个request是不是可以重试。
  5. complete: 查看结果是是不是正确的,如果是调用listeners的 onSuccess方法进行处理。
  6. fireSuccess: 调用listeners的 onSuccess方法进行处理
  7. fireFailure: 调用listeners的 onFail方法进行处理
  8. addListener: 添加监听者
  9. compose: 将一种类型的RequestFuture 转化为另外一种类型
  10. chain 将一个 RequestFuture 转化为RequestFutureListener,并添加到监听者队列。

RequestFuture的使用方法:


RequestFuture<ClientResponse> future = client.send(api, request);
client.poll(future); if (future.succeeded()) {
ClientResponse response = future.value();
// Handle response
} else {
throw future.exception();
}

当返回了RequestFuture ,因为逻辑要求,要转化为另外一种RequestFuture。

RequestFutureAdapter<F, T> 就是用来处理这种需求的。


public abstract class RequestFutureAdapter<F, T> { public abstract void onSuccess(F value, RequestFuture<T> future); public void onFailure(RuntimeException e, RequestFuture<T> future) {
future.raise(e);
}
}

HeartBeat

HeartBeat 主要有两个类,一个是HeartBeat类,用来管理heartBeat,一个是HeartbeatThread,用来和服务器的coordinator进行通信。

HeartBeat

作为一个心跳管理类,HeartBeat保存了下面几个变量:

//和coordinator通信的最长时间,如果超过sessionTimeout,就认为coordinator挂了
private final long sessionTimeout;
// 心跳间隔, 正常来说每次的时间间隔都是这个值
private final long heartbeatInterval;
// consumer发送心跳的最长间隔,如果超过这个间隔,就认为consumer脱离了消费组
private final long maxPollInterval;
// 返回失败后,重试等待的时间
private final long retryBackoffMs;
// 上次发送的时间
private volatile long lastHeartbeatSend; // volatile since it is read by metrics
// 上次接收到返回的时间
private long lastHeartbeatReceive;
// 上次重置session的时间,重新加入消费组以及重启thread都会重置为当前时间。
//它会和lastHeartbeatSend做比较,那个时间比较晚,就使用哪个作为上次发送哦的时间
private long lastSessionReset;
// consumer每次调用发送心跳的时间,如果now - lastPoll > maxPollInterval 就认为consumer maybeLeaveGroup
private long lastPoll;
// 心跳返回错误,就设置为true,这时候就将发送的时间间隔设置为retryBackoffMs
private boolean heartbeatFailed;

HeartBeat 最重要的作用就是计算当前到下次要发送heartbeat的时间间隔。

    public long timeToNextHeartbeat(long now) {
long timeSinceLastHeartbeat = now - Math.max(lastHeartbeatSend, lastSessionReset);
final long delayToNextHeartbeat;
if (heartbeatFailed)
delayToNextHeartbeat = retryBackoffMs;
else
delayToNextHeartbeat = heartbeatInterval; if (timeSinceLastHeartbeat > delayToNextHeartbeat)
return 0;
else
return delayToNextHeartbeat - timeSinceLastHeartbeat;
}

HeartBeatThread

HeartBeatThread 的主要逻辑就是等待下次要发送的时间,发送一次心跳,并查看返回值。

它对AbstractCoordinator.this进行了同步, 然后判断当前满足发送心跳的条件后,通过sendHeartbeatRequest发送心跳请求。心跳包含下面的内容:

private final String groupId;
private final int groupGenerationId;
private final String memberId;

SubscriptionState

这个类用来保存消费者消费的topic, partition, offset的信息。

consumer通过这个类subscribe topic。

这个类里面最重要的变量应该就是:

   private final PartitionStates<TopicPartitionState> assignment;

assignment 里面保存了这个consumer分配到的TopicPartition,以及这个parition当前的消费状态。

PartitionStates 类分装一个LinkedHashMap,它保存了<TopicPartition, TopicPartitionState>键值对。

TopicPartition里面包含了

private final int partition;
private final String topic;

TopicPartitionState 包含了


private Long position; // last consumed position
private OffsetAndMetadata committed; // last committed position
private boolean paused; // whether this partition has been paused by the user
private OffsetResetStrategy resetStrategy; // the strategy to use if the offset needs resetting

通过上面这两个变量就知道了当前consumer的操作状态,所有的函数基本都是围绕着assignment 进行操作。

Fetcher

fetcher负责从broker中拉取数据,并保存在一个队列中。consumer 在poll 的时候,首先会从这个队列中拿一部分数据进行处理。如果队列中没有数据了,fetcher 会再次拉取数据。

fetcher会通过sendFetches拉取数据, 并将结果保存在

private final ConcurrentLinkedQueue<CompletedFetch> completedFetches;中。 然后 consumer在poll 的时候,就会调用fetchedRecords从completedFetches中拉取数据。

了解了上面这些信息,再看pollOnce的逻辑,就明白多了:

    private Map<TopicPartition, List<ConsumerRecord<K, V>>> pollOnce(long timeout) {
coordinator.poll(time.milliseconds()); // fetch positions if we have partitions we're subscribed to that we
// don't know the offset for
//更新offset
if (!subscriptions.hasAllFetchPositions())
updateFetchPositions(this.subscriptions.missingFetchPositions()); // if data is available already, return it immediately
// 如果 completedFetches 队列中有数据,就直接拿数据
Map<TopicPartition, List<ConsumerRecord<K, V>>> records = fetcher.fetchedRecords();
if (!records.isEmpty())
return records; // send any new fetches (won't resend pending fetches)
// 准备好发送请求
fetcher.sendFetches(); long now = time.milliseconds();
long pollTimeout = Math.min(coordinator.timeToNextPoll(now), timeout);
// 发送请求到服务端,但是如果之前发送的fectch请求还在路上的话,就block等待。
client.poll(pollTimeout, now, new PollCondition() {
@Override
public boolean shouldBlock() {
// since a fetch might be completed by the background thread, we need this poll condition
// to ensure that we do not block unnecessarily in poll()
return !fetcher.hasCompletedFetches();
}
}); // after the long poll, we should check whether the group needs to rebalance
// prior to returning data so that the group can stabilize faster
if (coordinator.needRejoin())
return Collections.emptyMap();
// 再次返回数据
return fetcher.fetchedRecords();
}

Kafka Consumer2的更多相关文章

  1. 11:57:24 [org.springframework.kafka.KafkaListenerEndpointContainer#0-0-C-1] WARN o.apache.kafka.clients.NetworkClient - [Consumer clientId=consumer-2, groupId=jiatian_api] 3 partitions have leader……

    错误如下: 11:57:24 [org.springframework.kafka.KafkaListenerEndpointContainer#0-0-C-1] WARN  o.apache.kaf ...

  2. Kafka设计解析(四)- Kafka Consumer设计解析

    本文转发自Jason’s Blog,原文链接 http://www.jasongj.com/2015/08/09/KafkaColumn4 摘要 本文主要介绍了Kafka High Level Con ...

  3. Kafka设计解析(一)- Kafka背景及架构介绍

    本文转发自Jason’s Blog,原文链接 http://www.jasongj.com/2015/01/02/Kafka深度解析 背景介绍 Kafka简介 Kafka是一种分布式的,基于发布/订阅 ...

  4. ELK+Kafka集群日志分析系统

    ELK+Kafka集群分析系统部署 因为是自己本地写好的word文档复制进来的.格式有些出入还望体谅.如有错误请回复.谢谢! 一. 系统介绍 2 二. 版本说明 3 三. 服务部署 3 1) JDK部 ...

  5. Kafka深度解析

    本文转发自Jason’s Blog,原文链接 http://www.jasongj.com/2015/01/02/Kafka深度解析 背景介绍 Kafka简介 Kafka是一种分布式的,基于发布/订阅 ...

  6. Kafka深度解析,众人推荐,精彩好文!

    作者: Jason Guo 背景介绍 Kafka简介 Kafka是一种分布式的,基于发布/订阅的消息系统.主要设计目标如下: 以时间复杂度为O(1)的方式提供消息持久化能力,并保证即使对TB级以上数据 ...

  7. kafka设计原理介绍

    背景介绍 Kafka简介 Kafka是一种分布式的,基于发布/订阅的消息系统.主要设计目标如下: 以时间复杂度为O(1)的方式提供消息持久化能力,即使对TB级以上数据也能保证常数时间的访问性能 高吞吐 ...

  8. kafka基本原理学习

    下载安装地址:http://kafka.apache.org/downloads.html  原文链接:http://www.jasongj.com/2015/01/02/Kafka深度解析 Kafk ...

  9. kafka概念

    一.结构与概念解释 1.基础概念 topics: kafka通过topics维护各类信息. producer:发布消息到Kafka topic的进程. consumer:订阅kafka topic进程 ...

随机推荐

  1. Tomcat 初探(三)多项目部署

    起因 昨天房东找我说最近物价飞涨,要涨我房租,混不下去了,得要求老板涨工资.一大清早就去找老板,老板看了看我,让我发布先两个网站:一个前台网站 frontend,给用户用:一个后台管理网站 backe ...

  2. Spring《三》ref 引用其他bean

    local属性 1.被引用id必须在同一个xml中. 2.被引用id必须使用id命名. 优点提前检查所使用的bean id是否正确. Bean属性 1.Bean指定的id可以在不同的xml中. 2.B ...

  3. Exception异常常见属性

    废话少说,直接上代码: try { int n = Convert.ToInt32("@"); } catch(Exception ex) { Console.WriteLine( ...

  4. SQlException 对象名无效

  5. 动态修改SeekBar的颜色

    方法一 1. 需求:需要改变其默认颜色,样式 2.滑竿样式 seekbar.xml <?xml version="1.0" encoding="utf-8" ...

  6. The 2018 ACM-ICPC Asia Qingdao Regional Contest, Online J Press the Button

    BaoBao and DreamGrid are playing a game using a strange button. This button is attached to an LED li ...

  7. POSIX Threads

    POSIX Threads, usually referred to as pthreads, is an execution model that exists independently from ...

  8. CSS——背景图像区域

    background-clip属性 background-clip属性指定背景绘制区域 语法 background-clip:border-box|padding-box|content-box; b ...

  9. 《Let's Build A Simple Interpreter》之 Golang 版

    一直以来对编译器/解释器等都较有兴趣.我非科班出身,当初还在大学时,只是马马虎虎看完了<编译原理>之类教材,上机非常少,对龙书之类圣经也只是浅尝辄止而已.工作至今,基本已将编译原理相关知识 ...

  10. [中文] 以太坊(Ethereum )白皮书

    以太坊(Ethereum ):下一代智能合约和去中心化应用平台 翻译|巨蟹 .少平 译者注|中文读者可以到以太坊爱好者社区(www.ethfans.org)获取最新的以太坊信息. 当中本聪在2009年 ...