集群规划,3个容器,由最初的centos:latest镜像开始制作
主机名IP地址
kafka-node1172.19.0.71
kafka-node2172.19.0.72
kafka-node3172.19.0.73
宿主机(虚拟机centos6.5)10.20.0.128
172.19.0.0/16网段是docker内部使用的桥接网段,外网是无法直接访问的
安装和配置zookeeper
下载解压添加到环境变量即可,zoo.cfg配置如下
server.1=kafka-node1:2888:3888 server.2=kafka-node2:2888:3888
server.3=kafka-node3:2888:3888
注意配置的data目录下面的myid文件需要对应的id编号即可
安装和配置kafka
下载解压添加到环境变量,server.properties修改如下参数:
broker.id=1 //1,2,3因为配了3台 listeners=PLAINTEXT://kafka-node1:9092
//这个参数非常重要,想要外网访问docker内的集群,只能配置主机名,不能配置IP地址 zookeeper.connect=172.19.0.71:2181,
172.19.0.72:2181,172.19.0.73:2181 broker.id=2 listeners=PLAINTEXT:
//kafka-node2:9093 //注意不要在用9092端口,最好和docker暴露出去的端口一致 zookeeper.connect=172.19.0
.71:2181,172.19.0.72:2181,172.19.0.73:2181 broker.id=3 listeners=PLAINTEXT:
//kafka-node3:9094 zookeeper.connect=172.19.0.71:2181,172.19.0.72:2181,172.19.0
.73:2181
其他具体细节的配置参照官网说明,作为测试,默认不会有什么影响
Docker容器创建语句
docker run -d --name kafka-node1 --ip 172.19.0.71 --net mariadb-net -p 9092:
9092 -v /home/kafka-node1:/mnt -i -t cluster/hadoop:1.1-kafka /bin/bash docker
run -d --name kafka-node2 --ip172.19.0.72 --net mariadb-net -p 9093:9093 -v
/home/kafka-node2:/mnt -i -t cluster/hadoop:1.1-kafka /bin/bash docker run -d
--name kafka-node3 --ip172.19.0.73 --net mariadb-net -p 9094:9094 -v
/home/kafka-node3:/mnt -i -t cluster/hadoop:1.1-kafka /bin/bash
(把镜像换成centos:latest即可)
启动zookeeper
在3台机器上分别执行
zkServer.sh start
启动kafka集群
在3台机器上分别执行
kafka-server-start.sh -daemon /usr/local
/kafka/config/server.properties(修改成自己的地址)
本机测试
创建topic kafka-topics.sh --create --zookeeper kafka-node1:2181
--replication-factor1 --partitions 1 --topic test1 发送一些消息 kafka-console
-producer.sh --broker-list kafka-node1:9092 --topic test1 //注意这里不能在用localhost
查看消息 kafka-console-consumer.sh --bootstrap-server kafka-node2:9092 --topic
test1 --from-beginning
本机测试发现没有问题
Java客户端测试(其他机器,可以访问宿主机,但不能访问docker)
参照官网构建maven项目,代码如下:
public class DemoProducer { public static void main(String[] args) { long
events =10; Random rnd = new Random(); Properties props = new Properties();
props.put("bootstrap.servers", "10.20.0.128:9092"); props.put("acks", "all");
props.put("retries", 0); props.put("batch.size", 16384); props.put("linger.ms",
1); props.put("buffer.memory", 33554432); props.put("key.serializer",
"org.apache.kafka.common.serialization.StringSerializer"); props.put(
"value.serializer", "org.apache.kafka.common.serialization.StringSerializer");
Producer<String, String> producer = new KafkaProducer<>(props); for (long
nEvents =0; nEvents < events; nEvents++) { long runtime = new Date().getTime();
String ip = "192.168.2." + rnd.nextInt(255); String msg = runtime +
",www.example.com," + ip; ProducerRecord<String, String> data = new
ProducerRecord<String, String>("test1", msg); producer.send(data);
System.out.println(nEvents); } producer.close(); } }
发现一直卡在那里,最终以超时异常退出,或者报broker找不到的错误,跟进去之后发现,程序获得了cluster集群的信息,包括节点和分区等元信息,但是无法进一步访问,因为返回的信息是kafka-node1、kafka-node2和kafka-node3,这就是为什么在kafka的配置中不要配IP地址的原因,如果返回的是IP地址,那么肯定是无法访问的,现在返回的是主机名,很简单,在客户端的hosts文件中添加:
10.20.0.128 kafka-node1 10.20.0.128 kafka-node2 10.20.0.128 kafka-node3
把所有的主机名都映射到宿主机的IP,OK,问题解决
热门工具 换一换