原创/朱季谦

最近在阅读Kafka的源码,想可以在阅读过程当中,在代码写一些注释,便决定将源码部署到本地运行。

日常开发过程中,用得比较多一个版本是Kafka2.7版本,故而在MacBook Pro笔记本上用这个版本的源码进行搭建,进行Kafka源码的阅读学习。在搭建的过程当中,遇到不少坑,顺便记录了下来,方便以后重新搭建时,不至于又从头开始。

在本地搭建Kafka2.7源码,需要准备以下环境,我本地用的是MacBook Pro M1笔记本,windows的话应该也是类似思路:

  • Zulu JDK1.8
  • Scala 2.13.1
  • Gradle6.6
  • Zookeeper3.4.6
  • Kafka2.7

基于以上需要的环境,一一讲解。

一、Zulu JDK1.8

这个没啥好讲的,基本用MBP做开发的,几乎都有安装了一个JDK,区别是不同版本而已。我用的是OpenJDK 的Zulu JDK1.8版本,印象中是可以通过直接下载 .dmg 格式一键安装的,同时会自动配置好系统环境,默认安装路径在 /Library/Java/JavaVirtualMachines。

二、Scala 2.13.1

我没有在系统里安装Scala,而是直接用IDEA的。

按照Preferences -> Plugins -> 选择Scala点击Installed。

这样可以基于IDEA选择不同版本的Scala JDK——

三、安装Gradle6.6

可以通过官网https://gradle.org/releases/下载Gradle6.6版本——

官网下载,若是国内下载会很慢,我将当时下载的安装包放在了百度网盘里,可以直接网盘下载——

网盘链接: https://pan.baidu.com/s/1zmV2LNan0-lNEndPZ-H_Qw 提取码: agu5

下载下来后,直接解压,我放在了目录/Users/helloword/software/gradle-6.6,在mac终端执行指令——

  1. vim ~/.bash_profile

在bash_profile文件里加入以下内容,这里的GRADLE_HOME即解压存放gradle-6.6的目录——

  1. GRADLE_HOME=/Users/helloword/software/gradle-6.6
  2. export GRADLE_HOME

保存,执行source ~/.bash_profile刷新,输入gradle -v验证一下,若是出现以下信息,表示gradle安装成功——

  1. zhujiqian@zhujiqiandeMacBook-Pro ~ % gradle -v
  2. ------------------------------------------------------------
  3. Gradle 6.6
  4. ------------------------------------------------------------
  5. Build time: 2020-08-10 22:06:19 UTC
  6. Revision: d119144684a0c301aea027b79857815659e431b9
  7. Kotlin: 1.3.72
  8. Groovy: 2.5.12
  9. Ant: Apache Ant(TM) version 1.10.8 compiled on May 10 2020
  10. JVM: 1.8.0_282 (Azul Systems, Inc. 25.282-b08)
  11. OS: Mac OS X 12.5.1 aarch64

三、Zookeeper3.4.6安装

同理,避免读者额外去找这个包,我把它放到了百度网盘上——

链接: https://pan.baidu.com/s/1sTJVzDH5q4Jw5biAzTs3Mw 提取码: 6v87

3.1、分别将zookeeper-3.4.6.tar.gz拷贝到三台机器上,例如下面三台机器上,放到app目录下——

服务器名字 服务器IP
hadoop1 192.168.31.130
hadoop2 192.168.31.131
hadoop3 192.168.31.132

3.2、在三台机器的/app/zookeeper-3.4.6目录下,各创建一个data目录,然后各建立一个命名为myid的文件,分别按照以下方式写入一个数字——

  • 192.168.31.130的/app/zookeeper-3.4.6/data/myid写入数字1
  • 192.168.31.130的/app/zookeeper-3.4.6/data/myid写入数字2
  • 192.168.31.130的/app/zookeeper-3.4.6/data/myid写入数字3

cat查看192.168.31.130的/app/zookeeper-3.4.6/data/myid,值为1——

3.3、在192.168.31.130的/app/zookeeper-3.4.6/conf/目录下,其本身就有一个zoo_sample.cfg文件,通过cp zoo_sample.cfg zoo.cfg指令复制生成一个zoo.cfg文件,在zoo.cfg文件里修改为以下内容——

  1. tickTime=2000
  2. initLimit=10
  3. syncLimit=5
  4. dataDir=/app/zookeeper-3.4.6/data
  5. quorumListenOnAllIPs=true
  6. clientPort=2181
  7. dataLogDir=/app/zookeeper-3.4.6/dataLog
  8. server.1=192.168.31.130:2888:3888
  9. server.2=192.168.31.131:2888:3888
  10. server.3=192.168.31.132:2889:3889

保存完成后,分别复制到192.168.31.131、192.168.31.132这两台机器的/app/zookeeper-3.4.6/conf/目录下——

  1. scp zoo.cfg root@192.168.31.131:/app/zookeeper-3.4.6/conf/
  2. scp zoo.cfg root@192.168.31.132:/app/zookeeper-3.4.6/conf/

3.4、然后,就可以正常启动了,分别在三台机器的/app/zookeeper-3.4.6/bin目录下,执行./zkServer.sh start,执行完成后,通过指令执行./zkServer.sh status 观察集群状态,若是如下mode字段显示follower或者leader的话,说明集群已经成功启动——

四、Kafka2.7源码部署

4.1、源码部署搭建

读者可以自行到官网https://kafka.apache.org/downloads下载

当然,也可以直接从网盘下载,我已经放到网盘了,后续等我阅读完后,会把有源码注释的,同步到网盘里——

链接: https://pan.baidu.com/s/1KhW8V5UIcgtvXlCfAMNZeA 提取码: 31te

我把源码下载到目录/Users/helloword/software/kafka/kafka-2.7.0-src里。

Kafka源码需要依赖Gradle构建代码,就类似SpringBoot依赖Maven来构建代码,故而在将Kafka源码导入Idea前,先通过Gradle命令进行环境构建。

打开mac的终端,进入到源码路径——

然后分别执行以下指令——

  1. #更新gradle
  2. gradle
  3. #只需执行一次,会在当前目录的/gradle/wrapper/目录里生成一个gradle-wrapper.jar
  4. gradle wrapper

执行以上指令后,主要生成一个gradle-wrapper.jar,它是用来构建项目及打包的。

接下来,分别继续执行以下指令,这部分指令运行很慢,需要一段时间——

  1. #在 Gradle 项目中构建可执行的 JAR 文件
  2. ./gradlew jar
  3. #构建的项目中生成 IntelliJ IDEA 的工程文件和配置,若是用的eclipse,就运行./gradlew eclipse
  4. ./gradlew idea
  5. #生成源代码 JAR 文件
  6. ./gradlew srcJar

执行完以上指令,完成Gradle的代码运行环境,就可以通过Idea导入Kafak2.7源码——

正常情况下,左边栏会出现Gradle菜单选项,若没有的话,就双击源码里的build.gradle后,选择Link Gradle Project——

这时候,源码项目真正成为一个Gradle构建的项目,可以看到右边菜单多了一个Gradle菜单选项,点击,可以看到Gradle栏目里出现了一个kafka-2.7.0-src,双击后,选择Reload Gradle Project就可以加载项目及依赖了。

4.2、源码运行

4.2.1、源码运行打印日志

若要在源码里运行能够打印日志,需要满足以下两个条件——

1、复制config的log4.properties到core的 resources目录

2、在build.gradle的project(':core') 的dependencies {}增加log4配置

4.2.1.1、复制config的log4.properties到core的 resources目录

在源码/core/src/main/目录下,新建一个resource资源目录。

而在源码的config目录下,有一个log4j.properties。

可以直接将/config/log4j.properties复制到/core/src/main/resources目录里——

当然,直接复制过来时,运行时,可能只会出现以下打印,发现log4j.properties并没有起作用——

这时候就需要接下来在build.gradle增加一些配置。

4.2.1.2、在build.gradle的project(':core') 的dependencies {}增加log4配置

在build.gradle里找到project(':core') {}里的dependencies {}处,增加以下配置——

  1. compile group: 'org.slf4j', name: "slf4j-api", version: "1.7.28"
  2. compile group: 'org.slf4j', name: "slf4j-log4j12", version: "1.7.28"

配置完以上信息后,运行日志时可能还会出现以下异常——

  1. log4j:ERROR setFile(null,true) call failed.
  2. java.io.FileNotFoundException: /server.log (Read-only file system)
  3. at java.io.FileOutputStream.open0(Native Method)
  4. at java.io.FileOutputStream.open(FileOutputStream.java:270)
  5. at java.io.FileOutputStream.<init>(FileOutputStream.java:213)
  6. at java.io.FileOutputStream.<init>(FileOutputStream.java:133)
  7. at org.apache.log4j.FileAppender.setFile(FileAppender.java:294)
  8. at org.apache.log4j.FileAppender.activateOptions(FileAppender.java:165)
  9. at org.apache.log4j.DailyRollingFileAppender.activateOptions(DailyRollingFileAppender.java:223)

我当时的解决该异常的方式是,统一将log4.properties的日志出现以上异常的路径${kafka.logs.dir}改成指定的/Users/helloword/logs例如,/server.log等,统一改成,就正常了/Users/helloword/logs/server.log,就正常了。

4.2.2、修改源码的config/server.properties配置

在运行kafka服务前,需要修改config/server.properties配置里一些信息,主要改两处地方,分别是连接的zookeeper路径和kafka的broker的ip——

  1. broker.id=0 #默认的就好
  2. listeners=PLAINTEXT://192.168.31.110:9092 #改成你的主机ip,需要注意一点是,该ip需要能跟你配置的zookeeper通信
  3. zookeeper.connect=192.168.31.130:2181,192.168.31.130:2181,192.168.31.130:2181 #zookeeper集群地址

4.2.3、配置Kakfa运行的server、consumer、producer三个进程

4.2.3.1、server

按照以下信息配置一个server应用服务——

配置完,点击启动,若打印类似以下正常日志,说明成功了——

4.2.3.2、consumer

这里的--topic test01 --bootstrap-server 192.168.31.110:9092里的ip,即配置config/server.properties文件里listeners=PLAINTEXT://192.168.31.110:9092对应的ip。

该消费者表示监听topic为test01。

运行正常,日志打印同样没问题——

4.2.3.3、producer

跟consumer配置类似——

配置完成后,运行,若没有问题,可以直接在日志控制尝试模拟生产者发送消息,例如,发送一个hello world——

查看consumer端的日志打印,若能收到消息,说明kafka的生产者和消费者能正常进行消息发送了,可以基于这开始debug阅读源码了——

整个kafka2.7版本源码搭建,按照以上步骤就搭建完成。

后续我会将阅读源码的总结写成系列文章。

最近开了一个公众号,方便用来分类归纳自己写的博客,可以关注我的公众号【写代码的朱季谦】。

kafka源码阅读之MacBook Pro M1搭建Kafka2.7版本源码运行环境的更多相关文章

  1. Kafka 0.10.1版本源码 Idea编译

    Kafka 0.10.1版本源码 Idea编译 1.环境准备 Jdk 1.8 Scala 2.11.12:下载scala-2.11.12.msi并配置环境变量 Gradle 5.6.4: 下载Grad ...

  2. Spring各版本源码下载

    spring framework 各版本源码下载地址 现在spring的源码下载地址真是不好找,这次终于找到了.记录一下,以帮助需要的朋友. https://github.com/spring-pro ...

  3. spring各个版本源码

    各版本源码下载地址 http://maven.springframework.org/release/org/springframework/spring/

  4. [转帖]nginx1.17.2版本源码安装

    nginx1.17.2版本源码安装 原创: 沧海书生 Ansible爱好者 昨天 公众号里面的内容 这里简单测试了下 在x86的虚拟机里面编译安装 nginx 仅make make install n ...

  5. 《k8s-1.13版本源码分析》- Scheduler启动前逻辑

    本文原始地址(gitbook格式):https://farmer-hutao.github.io/k8s-source-code-analysis/core/scheduler/before-sche ...

  6. 《k8s-1.13版本源码分析》-源码调试

    源码分析系列文章已经开源到github,地址如下: github:https://github.com/farmer-hutao/k8s-source-code-analysis gitbook:ht ...

  7. 最全SDWebImage-3.8版本源码阅读详解

    一.前言 SDWebImage,非常友好的网络图片加载第三方框架,在GitHub中已经获得了15000++的star,链接地址:https://github.com/rs/SDWebImage 本人分 ...

  8. Res-net 标准版本源码差异-官方源码示例

    # resnet https://github.com/tensorflow/models/blob/master/research/slim/nets/resnet_v1.py https://gi ...

  9. 《k8s-1.13版本源码分析》-调度优选

    源码分析系列文章已经开源到github,地址如下: github:https://github.com/farmer-hutao/k8s-source-code-analysis gitbook:ht ...

  10. 《k8s-1.13版本源码分析》上github

    要干嘛? 猪年新气象,今年开始,kubernetes源码分析系列文章主战场从微信公众号转至github,完全使用Markdown重写,使用gitbook生成web页面,支持在线阅读,导出pdf等各种玩 ...

随机推荐

  1. 使用SemanticKernel 进行智能应用开发(2023-10更新)

    以OpenAI 的ChatGPT 所掀起的GenAI 快速创新浪潮,其中连接LLM 和 应用之间的桥梁的两大开源项目:LangChain[1]和Semantic Kernel[2] ,在半年前写过一篇 ...

  2. os --- 多种操作系统接口¶

    os.path --- 常用路径操作 源代码: Lib/posixpath.py (用于 POSIX) 和 Lib/ntpath.py (用于 Windows). 此模块实现了一些有用的路径名称相关函 ...

  3. ERROR: <bits/stdc++.h>, 'cstdalign' file not found, running C++17

    Modified 1 year, 1 month ago Viewed 9k times 4 I'm trying to run a piece of code in Visual Studio Co ...

  4. Java 集合的排序(正序倒序)、查找元素的下边、最大值、最小值

    Java 集合的排序(正序倒序).查找元素的下边.最大值.最小值 集合的排序 集合查找对应元素的下标 集合的最大最小值 集合的排序 使用Collections.sort()排序,默认是递增.加上比较器 ...

  5. 《最新出炉》系列初窥篇-Python+Playwright自动化测试-21-处理鼠标拖拽-番外篇

    1.简介 前边宏哥拖拽有提到那个反爬虫机制,加了各种参数,以及加载js脚本文件还是有问题,偶尔宏哥好像发现了解决问题的办法,看到了黎明的曙光,宏哥就说试一下看看行不行,万一实现了.结果宏哥试了结果真的 ...

  6. Flask后端开发(一)-基础知识和前期准备

    目录 1.背景介绍 1.1. 项目背景 1.2. 项目难点 1.3. 项目环境 2. flask后端开发实现的功能 3. flask部署和前后端对接 3.1. flask运行配置和服务器部署 3.2. ...

  7. [ABC276Ex] Construct a Matrix

    没有题解,所以来写一篇. Description 构造一个 \(N\times N\) 的矩阵 \(A\),其中 \(A_{i,j}\in {0,1,2}\),要求同时满足 \(Q\) 条限制. 每条 ...

  8. JUC并发编程学习笔记(十二)Stream流式计算

    Stream流式计算 什么是Stream流式计算 大数据:存储+计算 集合.MySql这些的本质都是存储东西的: 计算都应该交给流来操作! 一个案例说明:函数式接口.lambda表达式.链式编程.St ...

  9. P2360 地下城主

    题目大意 背景是逃离\(3D\)地下监狱,也就是三维样例,你可以前往所在小格的前方,后方,左方,右方,上层,下层的小格,'.'表示可走,'x'表示墙壁,'S'表示起点,'E'表示终点.每走一小格花费一 ...

  10. Linux TTY/PTS

    转载:https://segmentfault.com/a/1190000009082089 当我们在键盘上敲下一个字母的时候,到底是怎么发送到相应的进程的呢?我们通过ps.who等命令看到的类似tt ...