docker搭建zookeeper集群和kafka集群并使用Java測(cè)試詳解
本人也是在學(xué)習(xí)kafka中,本人只有筆記本電腦里的一臺(tái)Linux虛擬機(jī)這么一個(gè)小環(huán)境,要搭建kafka集群環(huán)境最好的方式應(yīng)該就是容器技術(shù)了,于是花了兩天時(shí)間,嘗試用docker搭建zookeeper和kafka集群環(huán)境
前置要求
- 在虛擬機(jī)中安裝好JDK
- 虛擬機(jī)安裝好docker和docker-compose
- 集群環(huán)境中涉及到的端口比較多,建議學(xué)習(xí)中,直接把虛擬機(jī)防火墻關(guān)了,省得費(fèi)事
1.拉相關(guān)鏡像
我的鏡像:
2.設(shè)置容器的網(wǎng)絡(luò)
名稱是zookeeper_kafka
docker network create --subnet 172.19.0.0/24 --gateway 172.19.0.1 zookeeper_kafka
設(shè)置完了可以查看一下:
docker network ls

3.搭建zookeeper集群
用docker-compose,3個(gè)zookeeper節(jié)點(diǎn),注意網(wǎng)絡(luò)的名字和端口映射,我的yml文件:
version: '2'
services:
zk_node1:
image: zookeeper:3.4
restart: always
hostname: zk_node1
container_name: zk_node1
ports:
- 2181:2181
volumes:
- ./zk_node1/data:/data
- ./zk_node1/datalog:/datalog
environment:
ZOO_MY_ID: 1
ZOO_SERVERS: server.1=0.0.0.0:2888:3888 server.2=zk_node2:2888:3888 server.3=zk_node3:2888:3888
networks:
zookeeper_kafka:
ipv4_address: 172.19.0.11
zk_node2:
image: zookeeper:3.4
restart: always
hostname: zk_node2
container_name: zk_node2
ports:
- 2182:2181
volumes:
- ./zk_node2/data:/data
- ./zk_node2/datalog:/datalog
environment:
ZOO_MY_ID: 2
ZOO_SERVERS: server.1=zk_node1:2888:3888 server.2=0.0.0.0:2888:3888 server.3=zk_node3:2888:3888
networks:
zookeeper_kafka:
ipv4_address: 172.19.0.12
zk_node3:
image: zookeeper:3.4
restart: always
hostname: zk_node3
container_name: zk_node3
ports:
- 2183:2181
volumes:
- ./zk_node3/data:/data
- ./zk_node3/datalog:/datalog
environment:
ZOO_MY_ID: 3
ZOO_SERVERS: server.1=zk_node1:2888:3888 server.2=zk_node2:2888:3888 server.3=0.0.0.0:2888:3888
networks:
zookeeper_kafka:
ipv4_address: 172.19.0.13
networks:
zookeeper_kafka:
external:
name: zookeeper_kafka
4.搭建kafka集群和kafka manager
同樣是3個(gè)節(jié)點(diǎn)
version: '2'
services:
broker1:
image: wurstmeister/kafka
restart: always
hostname: broker1
container_name: broker1
privileged: true
ports:
- 9091:9091
environment:
#KAFKA_BROKER_ID: 1
KAFKA_LISTENERS: PLAINTEXT://broker1:9091
KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://broker1:9091
KAFKA_ADVERTISED_HOST_NAME: broker1
KAFKA_ADVERTISED_PORT: 9091
KAFKA_ZOOKEEPER_CONNECT: zk_node1:2181,zk_node2:2181,zk_node3:2181
#JMX_PORT: 9988
volumes:
- ./broker1/docker.sock:/var/run/docker.sock
- ./broker1/logs:/kafka/kafka-logs-broker1
external_links:
- zk_node1
- zk_node2
- zk_node3
networks:
zookeeper_kafka:
ipv4_address: 172.19.0.21
broker2:
image: wurstmeister/kafka
restart: always
hostname: broker2
container_name: broker2
privileged: true
ports:
- 9092:9092
environment:
#KAFKA_BROKER_ID: 2
KAFKA_LISTENERS: PLAINTEXT://broker2:9092
KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://broker2:9092
KAFKA_ADVERTISED_HOST_NAME: broker2
KAFKA_ADVERTISED_PORT: 9092
KAFKA_ZOOKEEPER_CONNECT: zk_node1:2181,zk_node2:2181,zk_node3:2181
#JMX_PORT: 9988
volumes:
- ./broker2/docker.sock:/var/run/docker.sock
- ./broker2/logs:/kafka/kafka-logs-broker2
external_links: # 連接本compose文件以外的container
- zk_node1
- zk_node2
- zk_node3
networks:
zookeeper_kafka:
ipv4_address: 172.19.0.22
broker3:
image: wurstmeister/kafka
restart: always
hostname: broker3
container_name: broker3
privileged: true
ports:
- 9093:9093
environment:
#KAFKA_BROKER_ID: 3
KAFKA_LISTENERS: PLAINTEXT://broker3:9093
KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://broker3:9093
KAFKA_ADVERTISED_HOST_NAME: broker3
KAFKA_ADVERTISED_PORT: 9093
KAFKA_ZOOKEEPER_CONNECT: zk_node1:2181,zk_node2:2181,zk_node3:2181
#JMX_PORT: 9988
volumes:
- ./broker3/docker.sock:/var/run/docker.sock
- ./broker3/logs:/kafka/kafka-logs-broker3
external_links: # 連接本compose文件以外的container
- zk_node1
- zk_node2
- zk_node3
networks:
zookeeper_kafka:
ipv4_address: 172.19.0.23
kafka-manager:
image: sheepkiller/kafka-manager
restart: always
container_name: kafka-manager
hostname: kafka-manager
ports:
- "9000:9000"
links: # 連接本compose文件創(chuàng)建的container
- broker1
- broker2
- broker3
external_links: # 連接本compose文件以外的container
- zk_node1
- zk_node2
- zk_node3
environment:
ZK_HOSTS: zk_node1:2181,zk_node2:2181,zk_node3:2181
KAFKA_BROKERS: broker1:9091,broker2:9092,broker3:9093
APPLICATION_SECRET: letmein
KM_ARGS: -Djava.net.preferIPv4Stack=true
networks:
zookeeper_kafka:
ipv4_address: 172.19.0.10
networks:
zookeeper_kafka:
external: # 使用已創(chuàng)建的網(wǎng)絡(luò)
name: zookeeper_kafka
注意這里文件里的zookeeper節(jié)點(diǎn)名稱和kafka節(jié)點(diǎn)名稱要換成自己的
5. 啟動(dòng)集群
用docker-compose啟動(dòng)很方便的
先啟動(dòng)zookeeper集群:
docker-compose -f /home/docker/zookeeper/docker-compose.yml up -d
這里的-f選項(xiàng)讓我們可以指定yml,因此yml的名稱可以任意取,位置也可以任意放
如果需要關(guān)閉并刪除容器:
docker-compose -f /home/docker/zookeeper/docker-compose.yml down
然后啟動(dòng)kafka集群:
docker-compose -f /home/docker/zookeeper/docker-compose.yml up -d
啟動(dòng)沒問題的話,查看一下:docker ps

可以看到3個(gè)zookeeper和3個(gè)kafka,1個(gè)kafka-manager已經(jīng)啟動(dòng)好了,看起來很簡(jiǎn)單,但是這些花了我一天時(shí)間。。。
6.測(cè)試有沒有啟動(dòng)成功
6.1 kafka-manager測(cè)試
kafka的可視化工具也蠻多的,包括kafka-manager,kafka-eagle,kafka-tool等等,還有idea里面的kafka插件,本人都試了,因?yàn)楸救耸窍扔脄ookeeper單機(jī)和kafka單機(jī)測(cè)試的(也就是壓縮包直接安裝的方式),這些工具都能連接上,但是用docker單機(jī)集群之后,用kafka-tool就連接不上,然后比較坑的是kafka-eagle,其實(shí)kafka-eagle在這里面是最炫酷的,用起來也很爽,但是這玩意太耗內(nèi)存了,我的虛擬機(jī)實(shí)在是跑不動(dòng)它。。。我也是折騰了好久才發(fā)現(xiàn)的
回到正題,在上一步做完了之后,在Win10系統(tǒng)里,訪問http://虛擬機(jī)IP:9000就可以訪問kafka-manager了,一開始是空的,要create cluster,然后只需要隨意填一個(gè)名字,再填上zookeeper的集群,就填kafka的yml文件里面,kafka-manager配置的zookeeper集群就好了,然后save

看到這個(gè)集群的brokers是3,就說明成功了

接著我建了一個(gè)test的topic,partition=3,replica = 3

6.2 在shell終端測(cè)試
先進(jìn)入一個(gè)容器,然后使用kafka-console-producer.sh搞出一個(gè)生產(chǎn)者
指令清單:
docker ps -a docker exec -it 910 bash #注: 910是broker2的id前綴 cd /opt/kafka/bin/ #可以先查看一下topic列表看看是否連得通 kafka-topics.sh --bootstrap-server broker1:9091,broker2:9092,broker3:9093 --list kafka-console-producer.sh --broker-list broker1:9091,broker2:9092,broker3:9093 --topic test
截圖:


這個(gè)時(shí)候就進(jìn)入了生產(chǎn)者模式,hello 和kafka是我自己輸入
這個(gè)時(shí)候,復(fù)制一個(gè)shell會(huì)話,同樣進(jìn)入一個(gè)broker,然后使用消費(fèi)者模式
指令清單:
docker exec -it 910 bash cd /opt/kafka/bin/ kafka-console-consumer.sh --bootstrap-server broker1:9091,broker2:9092,broker3:9093 --topic test --from-beginning
就能收到我剛剛輸入的hello和kafka,也就說明測(cè)試成功了

7.使用Java連接集群
首先引入kafka依賴和Junit依賴,我的kafka版本好像是2.8.1
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.kafka</groupId>
<artifactId>kafka-clients</artifactId>
<version>2.8.1</version>
</dependency>
我的生產(chǎn)者代碼:
/**
* @author
* @Package PACKAGE_NAME
* @date 2021/12/19 12:36
*/
public class TestKafkaProducer {
private KafkaProducer<String, String> kafkaProducer;
@Before
public void before(){
Properties props = new Properties();
props.put("bootstrap.servers", "192.168.209.130:9091,192.168.209.130:9092,192.168.209.130:9093");
props.put("acks", "1");
props.put("retries", 0);
props.put("batch.size", 16384);
props.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer");
props.put("value.serializer", "org.apache.kafka.common.serialization.StringSerializer");
kafkaProducer = new KafkaProducer<String, String>(props);
}
@Test
public void testProduce() throws ExecutionException, InterruptedException {
for (int i = 0; i < 100;) {
Future<RecordMetadata> future = kafkaProducer.send(new ProducerRecord<String, String>("test", "key" + (++i), "value" + i));
future.get();
}
}
@After
public void close(){
kafkaProducer.close();
}
}
?。。?!重點(diǎn)
這個(gè)時(shí)候會(huì)發(fā)現(xiàn)怎么連都連不上kafka集群,然后在拉鉤教育的教程中看到了要在Win10的電腦中加hosts文件的映射,如下?。?!這里不是打廣告,是真的謝謝他們。
192.168.209.130 broker1 192.168.209.130 broker2 192.168.209.130 broker3
192.168.209.130是我虛擬機(jī)的IP,broker1,2,3是yml創(chuàng)建的kafka集群節(jié)點(diǎn),加上host映射就能連上了?。。。?/p>
跑生產(chǎn)者代碼,然后這個(gè)時(shí)候,我之前打開的shell端消費(fèi)者沒關(guān),正好消費(fèi)到了我上面寫的100條數(shù)據(jù)
于是我就不放消費(fèi)者的Java代碼出來了,能連上集群,其他的就是正常開發(fā)了。

8.重點(diǎn)總結(jié)
- kafka-eagle很耗內(nèi)存,機(jī)子內(nèi)存不夠的情況下慎用
- Java連接docker里的kafka集群,需要在Win10中加host映射
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
CentOS7 Docker防火墻的簡(jiǎn)單配置教程
這篇文章主要給大家介紹了關(guān)于CentOS7 Docker防火墻的簡(jiǎn)單配置方法,以及總結(jié)了docker在centos7下的一些坑,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考借鑒,下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧。2017-12-12
docker覆蓋鏡像默認(rèn)命令之docker?entrypoint詳解
entrypoint命令就是覆蓋ENTRYPOINT命令的,本文給大家介紹了docker覆蓋鏡像默認(rèn)命令之docker?entrypoint的相關(guān)知識(shí),需要的朋友可以參考下2023-10-10
詳解如何用docker安裝laravel開發(fā)環(huán)境
本篇文章主要介紹了詳解如何用docker安裝laravel開發(fā)環(huán)境,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-02-02
Docker 數(shù)據(jù)管理Named volume詳解
這篇文章主要介紹了Docker 數(shù)據(jù)管理Named volume詳解的相關(guān)資料,需要的朋友可以參考下2017-03-03
如何解決docker logs無法實(shí)時(shí)輸出腳本打印的內(nèi)容
這篇文章主要介紹了如何解決docker logs無法實(shí)時(shí)輸出腳本打印的內(nèi)容問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-07-07
Docker Buildx鏡像壓縮的實(shí)現(xiàn)
本文主要介紹了Docker Buildx鏡像壓縮的實(shí)現(xiàn),顯著減小鏡像體積并提升構(gòu)建效率,適用于多平臺(tái)構(gòu)建、CI/CD流水線等場(chǎng)景,支持多架構(gòu)并行構(gòu)建與高效壓縮算法,優(yōu)化存儲(chǔ)與傳輸性能,降低部署成本,感興趣的可以了解一下2026-05-05
Docker使用Calico網(wǎng)絡(luò)模式配置及問題處理方法
這篇文章主要介紹了Docker使用Calico網(wǎng)絡(luò)模式配置及問題處理,設(shè)計(jì)思想是Calico不使用隧道或者NAT來實(shí)現(xiàn)轉(zhuǎn)發(fā),而是巧妙的把所有二三層流量轉(zhuǎn)換成三層流量,并通過host上路由配置完成跨host轉(zhuǎn)發(fā),需要的朋友可以參考下2022-11-11
Docker Compose一鍵ELK部署的方法實(shí)現(xiàn)
這篇文章主要介紹了Docker Compose一鍵ELK部署的方法實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-01-01

