前言:kafka 2.8+已经 “抛弃” 了Zookeeper(CP模型,即要保证数据的强一致性,必然在可用性方面做出牺牲),使用了Raft
所以笔者这里选择了较稳定的2.7版本
一、工程目录结构
- bin: 启动脚本;
- clients:生产者和消费者代码;
- config: 配置文件;
- core : kafka server端,scala语言开发,实现了集群管理,分区副本管- 理,消息存储和消息获取,网络通信等功能;
- docs:kakfa文档
- examples:生产者消费者demo 启动脚本;
- streams:kafka 流相关代码;
- jmh-benchmarks:JMH测试;
- log4j-appender:日志处理;
- tools:工具包;
二、核心-core 目录
- admin包:执行管理命令的功能;
- api 包: 封装请求和响应DTO对象;
- cluster包:集群对象,例如Replica 类代表一个分区副本,Partition类代表一个分区;
- common包: 通用jar包;
- controller包: 和kafkaController(kc)相关的类,重点模块,一个kafka集群只有一个leader kc,该kc负责 分区管理,副本管理,并保证集群信息在集群中同步;
- coordinator包:组协调者相关,负责处理消费者组的代码;
- log包: 磁盘存储相关,重点模块;
- network包: 网络相关,重点模块,使用的是NIO,从这里可学习如何应用java 的NIO类;
- consumer包,producer好多废弃类,无需关注;
- server包: kafka实例的各种管理类,核心包,也是重点;
- tools: 工具类
三、核心-client目录
- clients 包:生产者producer 和消费者consumer的代码
- common 包:常用方法和工具包
- server 包:服务端方法接口
四、准备工作
1、启动Zookeeper
2、解决每次执行debug都要执行很多task,时间很久。需要修改Idea
这里两项都修改为Intellij IDEA
3、设置日志输出路径
kafka.logs.dir=/tmp/kafka-logs (自行定义,不定义则直接输出工程所在盘符)
五、开始阅读
先运行:core/src/main/scala/kafka/Kafka.scala
接着找到入口java类:这里我为了方便debug,已经修改了部分代码
examples/src/main/java/kafka/examples/KafkaConsumerProducerDemo.java
package kafka.examples;
import java.util.concurrent.CountDownLatch;
public class KafkaConsumerProducerDemo {
/**
* 读取源码入口
* @param args
* @throws InterruptedException
*/
public static void main(String[] args) throws InterruptedException {
// kafka默认都是通过异步发送消息
boolean isAsync = args.length == 0 || !args[0].trim().equalsIgnoreCase("sync");
CountDownLatch latch = new CountDownLatch(1);
// 启动一个Producer线程, 循环发送消息
Producer producerThread = new Producer(KafkaProperties.TOPIC, isAsync, null, false, 1, -1, latch);
producerThread.start();
//启动一个Consumer线程, 循环消费消息
/*Consumer consumerThread = new Consumer(KafkaProperties.TOPIC, "DemoConsumer", Optional.empty(), false, 1, latch);
consumerThread.start();
if (!latch.await(5, TimeUnit.MINUTES)) {
throw new TimeoutException("Timeout after 5 minutes waiting for demo producer and consumer to finish");
}*/
// consumerThread.shutdown();
System.out.println("All finished!");
}
}
到了这里我们就可以直接Debug开始阅读Kafka源码了