提出问题

近日助友 Docker 部署 Kafka 服务,服务日志启动正常,但客户端却无法连接

往日曾踩过此坑,然方法均源于博客,其语焉不详,不知为何不行,亦不知为何行,印象不甚深刻,耗费大量时间

为避此坑,特地学习官方文档相关章节,让我寻到珠丝马迹,请听我娓娓道来~

如嫌篇幅较长,可跳过验证,直奔结论

本文主要记录为何会出现无法连接到 Broker 的原因,想必看完本文你会知道该怎么做的

谨以此文献给那些因为无知而浪费的时光!

大胆猜测

Kafka的服务端称为 Broker,每个 Broker 启动时会将自己的 Broker 配置信息上报给 Zookeeper ,如,监听地址与端口号等,Kafka的客户端(生产者与消费者统称)要连接 Broker 需要经过一层认证,不通过认证就无法连接!

小心求证

测试环境:

  • GNU/Linux Debian 10 4.19.0内核
  • Docker:19.03.6
  • Docker-compose:1.17.1
  • 镜像:zookeeper:3.5.5
  • 镜像:wurstmeister/kafka:2.12-2.2.1

设计实验:

使用 docker 镜像部署一套单节点的 Zookeeper + Kafka

要求Broker监听自定义域名(主机名)与端口,服务启动后展示 ZookeeperBroker 的注册信息

使用客户端连接 Broker ,使用不同的 --bootstrap-server 组合方式,进行验证

开始实验

为了提高部署效率,这里提供一个简单可启动的 docker-compose-test.yml

version: "3.3"
services:
zookeeper:
image: zookeeper:3.5.5
restart: always
container_name: zookeeper
ports:
- "2181:2181"
expose:
- "2181"
environment:
- ZOO_MY_ID=1
kafka:
image: wurstmeister/kafka:2.12-2.2.1
restart: always
container_name: kafka
environment:
- KAFKA_BROKER_ID=1
- KAFKA_LISTENERS=PLAINTEXT://kafka:9090
- KAFKA_ZOOKEEPER_CONNECT=zookeeper:2181
- KAFKA_MESSAGE_MAX_BYTES=2000000
ports:
- "9090:9090"
depends_on:
- zookeeper

docker-compose-test.yml 放入你的目录,运行部署脚本

查看两者的日志,检查是否正常启动

docker logs -f zookeeper

docker logs -f kafka

可以看到 Kafka 已经注册成功

让我们查看一下,Zookeeper 中注册的 Broker 信息

docker exec -it zookeeper bash bin/zkCli.sh

输入 quit 退出

想到我们已经将Kafka监听的端口号已经映射到宿主机了,使用宿主机 IP 访问不就得了?

先创建个Topic

docker run -it --rm --network host wurstmeister/kafka:2.12-2.2.1 \
bash /opt/kafka/bin/kafka-topics.sh \
--bootstrap-server 192.168.1.19:9090 \
--create --topic logsTopic --partitions 1 --replication-factor 1

噢!又是这该死的错误!

想到刚才在 zookeeper 中看到的信息,要不我把 IP 换成 kafka 不就结了?

docker run -it --rm --network host wurstmeister/kafka:2.12-2.2.1 \
bash /opt/kafka/bin/kafka-topics.sh \
--bootstrap-server kafka:9090 \
--create --topic logsTopic --partitions 1 --replication-factor 1

不对,宿主机本身没有对 kafka 作映射,问题一定出在这里!

再次执行刚才的命令,没有输出,说明创建 Topic 成功!

生产一条消息测试下

docker run -it --rm --network host wurstmeister/kafka:2.12-2.2.1 \
bash /opt/kafka/bin/kafka-console-producer.sh \
--broker-list kafka:9090 --topic logsTopic

输入回车,发送消息; ctrl + c 断开连接

创建消费者,消费消息测试

docker run -it --rm --network host wurstmeister/kafka:2.12-2.2.1 \
bash /opt/kafka/bin/kafka-console-consumer.sh \
--bootstrap-server kafka:9090 --topic logsTopic --from-beginning

嗯,消费也成功了

归纳总结

这个实验说明了什么呢?

说明 Kafka 客户端在连接 Broker 的时候,Broker 将客户端发来的请求带的信息与 Broker 启动时上报给 Zookeeper 的信息 进行了比对,比对相同则认证通过,反之建立连接失败!

官方文档

通过耐心地查看 Kafka 的官方文档,终于在角落里看到她的影子!(好久不见妹子,看文档都眉清目秀的~)

比如下面这段:

From Kafka version 2.0.0 onwards, host name verification of servers is enabled by default for client connections as well as inter-broker connections to prevent man-in-the-middle attacks.

大意是讲通过这种认证hostname的机制,来避免中间人攻击

还有这段:

advertised.host.name: DEPRECATED: only used when advertised.listeners or listeners are not set. Use advertised.listeners instead. Hostname to publish to ZooKeeper for clients to use. In IaaS environments, this may need to be different from the interface to which the broker binds. If this is not set, it will use the value for host.name if configured. Otherwise it will use the value returned from java.net.InetAddress.getCanonicalHostName().

虽然这个参数已经标记为废弃了,但是她提供了个信息:如果设置主机名可能会被上报

最后看看这段

advertised.listeners: Listeners to publish to ZooKeeper for clients to use, if different than the listeners config property. In IaaS environments, this may need to be different from the interface to which the broker binds. If this is not set, the value for listeners will be used. Unlike listeners it is not valid to advertise the 0.0.0.0 meta-address.

也就是说,默认设置 advertised.listenerslisteners 的值相同,上报Zookeeper供客户端使用;无需绑定不同接口时,只需要设置 listeners 即可。

结论

Kafka 客户端在连接 Broker 的时候,Broker 将客户端发来的请求附加信息与 Broker 启动时上报给 Zookeeper 的 listeners参数信息、host(来自listeners的中间域名或主机名部分)、port (来自listeners的端口部分) 进行了验证,认证通过建立连接执行请求,反之建立连接失败

如果看完本文还不知如何去做,请参考https://www.cnblogs.com/hellxz/p/how_to_add_hosts_on_docker.html

写这篇文章费了好大的功夫,猜是一回事,弄明白又是一回事,如果本文对你有所帮助,欢迎点推荐与关注

引用:
https://kafka.apache.org/documentation.html

本文采用 CC BY 4.0 协议进行授权,转载请标注作者署名及来源。
https://www.cnblogs.com/hellxz/p/why_cnnect_to_kafka_always_failure.html

【原创】为什么我的 Kafka 总是连接失败呢?的更多相关文章

  1. ssh连接失败,排错经验

    一.场景描述 ssh连接服务器,发现连接失败,但是对应服务器的ip能够ping通. 场景: [root@yl-web ~]# ssh root@10.1.101.35 ssh_exchange_ide ...

  2. com.microsoft.sqlserver.jdbc.SQLServerException: 到主机 的 TCP/IP 连接失败。 java.net.ConnectException: Connection refused: connect

      问题描述:最简单的数据库连接报错,到主机  的 TCP/IP 连接失败.(win 7 操作系统) 错误信息: com.microsoft.sqlserver.jdbc.SQLServerExcep ...

  3. mysql客户端授权后连接失败问题

    在本地(192.168.1.152)部署好mysql环境,授权远程客户机192.168.1.%连接本机的mysql,在iptables防火墙也已开通3306端口.如下:mysql> select ...

  4. ORA-12545: 因目标主机或对象不存在, 连接失败

    ORA-12545: 因目标主机或对象不存在, 连接失败 1. 问题描述 XP系统下同时安装了AX1应用程序和升级版AX2,连接同一个在本机Oracle客户端上配置的连接实例,其中AX2显示链接成功, ...

  5. 【转】Java JDBC连接SQL Server2005错误:通过端口 1433 连接到主机 localhost 的 TCP/IP 连接失败

    错误原因如下: Exception in thread "main" org.hibernate.exception.JDBCConnectionException: Cannot ...

  6. GPRS连接失败问题

    备注:采用的是SIMCOM的SIM900模块 1. GPRS连接失败问题 2013.08.06测试9台C2000两次,两次之间是机器拿开电池,间隔40分钟左右,每次都出现一台(但不是同一台): ⑴9台 ...

  7. kafka+storm连接

    本项目为maven项目,需要添加必要的storm库,以及kafka依赖,使用storm自带的storm-kafka进行连接,根据自己集群环境 <dependency> <groupI ...

  8. Java JDBC连接SQL Server2005错误:通过port 1433 连接到主机 localhost 的 TCP/IP 连接失败

    错误原因例如以下: Exception in thread "main" org.hibernate.exception.JDBCConnectionException: Cann ...

  9. ssh连接失败,排错经验(转)

    一.场景描述 ssh连接服务器,发现连接失败,但是对应服务器的ip能够ping通. 场景: [root@yl-web ~]# ssh root@10.1.101.35 ssh_exchange_ide ...

随机推荐

  1. 金山wps的面试经历

    故事从两个月前开始说起吧. 前段时间突然想跳槽,原因也没啥,就是想折腾下,看看外面的世界?有一部分原因是想离家近一些稳定下来,博主上份工作坐标厦门,风景好的简直随便拍照就是大片. 不废话了,机缘巧合, ...

  2. vue2.0学习之动画

    下载animate.css <transition name="v"> <div class="content">需要做动画的内容< ...

  3. 头次接触wamp服务器、xampp,初次单独使用tomcat部署

    刚刚经过了近两天的接触wamp.xampp.tomcat的时光,真的爽 导师有个网站打不开了,就让我去弄,还有一个网站的后台密码忘了,让我帮忙找回来.我第一感觉就是第一个活不简单,第二个还不简单吗?打 ...

  4. Django学习之模板层

    三板斧 render,HttpResponse,redirectrender返回一个HTML页面,并且还能够给该页面传数据render内部原理: from django.template import ...

  5. 谷歌眼镜、亚马逊音箱,5G时代隐私或将面临更大颠覆

    别看现在的智能手机.平板电脑.可穿戴设备.智能家居等那么火爆,但离开网络它们其实什么也不是.当然,智能终端设备的迭进也是与网络制式不断向前演变相辅相成的,二者算是互相成就.不过也由此衍生出很多问题,尤 ...

  6. 3dmax2017卸载/安装失败/如何彻底卸载清除干净3dmax2017注册表和文件的方法

    3dmax2017提示安装未完成,某些产品无法安装该怎样解决呢?一些朋友在win7或者win10系统下安装3dmax2017失败提示3dmax2017安装未完成,某些产品无法安装,也有时候想重新安装3 ...

  7. CF-544:部分题目总结

    -------------------昨天打的重现赛,感觉是我打的发挥的最好的一场比赛了,六题都一次AC.那么就来总结一下吧 题目链接:http://codeforces.com/contest/11 ...

  8. make的工作方式

    摘自<跟我一起写Makefile> GUN的make工作时的执行步骤如下: 1)读入所有的Makefile. 2)读入被include的其他Makeifle. 3)初始化文件中的变量. 4 ...

  9. Golang Interface 解析

    转自 https://zhuanlan.zhihu.com/p/27652856 先看一段代码: 123456789101112 func (x interface{}) { if x == nil ...

  10. vue-cli 项目结构介绍

    感谢:https://www.jianshu.com/p/7006a663fb9f 总体框架 一个vue-cli的项目结构如下,其中src文件夹是需要掌握的,所以本文也重点讲解其中的文件,至于其他相关 ...