docker搭建zookeeper集群和kafka集群并使用Java測試詳解
本人也是在學(xué)習(xí)kafka中,本人只有筆記本電腦里的一臺Linux虛擬機(jī)這么一個小環(huán)境,要搭建kafka集群環(huán)境最好的方式應(yīng)該就是容器技術(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個zookeeper節(jié)點,注意網(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個節(jié)點
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é)點名稱和kafka節(jié)點名稱要換成自己的
5. 啟動集群
用docker-compose啟動很方便的
先啟動zookeeper集群:
docker-compose -f /home/docker/zookeeper/docker-compose.yml up -d
這里的-f選項讓我們可以指定yml,因此yml的名稱可以任意取,位置也可以任意放
如果需要關(guān)閉并刪除容器:
docker-compose -f /home/docker/zookeeper/docker-compose.yml down
然后啟動kafka集群:
docker-compose -f /home/docker/zookeeper/docker-compose.yml up -d
啟動沒問題的話,查看一下:docker ps

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

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

接著我建了一個test的topic,partition=3,replica = 3

6.2 在shell終端測試
先進(jìn)入一個容器,然后使用kafka-console-producer.sh搞出一個生產(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
截圖:


這個時候就進(jìn)入了生產(chǎn)者模式,hello 和kafka是我自己輸入
這個時候,復(fù)制一個shell會話,同樣進(jìn)入一個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,也就說明測試成功了

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();
}
}
!?。?!重點
這個時候會發(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é)點,加上host映射就能連上了?。。?!
跑生產(chǎn)者代碼,然后這個時候,我之前打開的shell端消費(fèi)者沒關(guān),正好消費(fèi)到了我上面寫的100條數(shù)據(jù)
于是我就不放消費(fèi)者的Java代碼出來了,能連上集群,其他的就是正常開發(fā)了。

8.重點總結(jié)
- kafka-eagle很耗內(nèi)存,機(jī)子內(nèi)存不夠的情況下慎用
- Java連接docker里的kafka集群,需要在Win10中加host映射
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
docker覆蓋鏡像默認(rèn)命令之docker?entrypoint詳解
entrypoint命令就是覆蓋ENTRYPOINT命令的,本文給大家介紹了docker覆蓋鏡像默認(rèn)命令之docker?entrypoint的相關(guān)知識,需要的朋友可以參考下2023-10-10
詳解如何用docker安裝laravel開發(fā)環(huán)境
本篇文章主要介紹了詳解如何用docker安裝laravel開發(fā)環(huán)境,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-02-02
Docker 數(shù)據(jù)管理Named volume詳解
這篇文章主要介紹了Docker 數(shù)據(jù)管理Named volume詳解的相關(guān)資料,需要的朋友可以參考下2017-03-03
如何解決docker logs無法實時輸出腳本打印的內(nèi)容
這篇文章主要介紹了如何解決docker logs無法實時輸出腳本打印的內(nèi)容問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-07-07
Docker使用Calico網(wǎng)絡(luò)模式配置及問題處理方法
這篇文章主要介紹了Docker使用Calico網(wǎng)絡(luò)模式配置及問題處理,設(shè)計思想是Calico不使用隧道或者NAT來實現(xiàn)轉(zhuǎn)發(fā),而是巧妙的把所有二三層流量轉(zhuǎn)換成三層流量,并通過host上路由配置完成跨host轉(zhuǎn)發(fā),需要的朋友可以參考下2022-11-11
Docker Compose一鍵ELK部署的方法實現(xiàn)
這篇文章主要介紹了Docker Compose一鍵ELK部署的方法實現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-01-01

