为什么kafka客户端需要配置 /etc/hosts文件

问题背景

  • 前段时间,遇到一个kafka集群部署在k8s中,而kafka客户端在另一个k8s集群的pod的容器中,kafka集群中配置的advertised_listeners便是hostname。然而当时我只知道kafka集群的ip地址,当在客户端直接使用ip操作broker的时候便报错无法解析一个hostname。
  • 当时不知道什么原因,只听同事说需要在kafka客户端对应的yaml文件中添加HostAliases字段然后重新部署kafka客户端所在的pod。 然后便可以访问了。
  • 不明所以然的我,查了一下hostAliases的使用发现没什么特别之处。然后查了listeners的使用也没有说是可以携带域名之类的
  • 最后查了一下kafka客户端的请求过程才明白是怎么回事(笔者接触kafka不久只是阅读过文档并没有了解到其客户端的请求过程和步骤,所以迷惑了这么久 - _ -)

kafka broker配置介绍

kafka listeners及其相关配置项的作用

先来看一下官方文档对kafka broker中有关listeners配置项的介绍:

名称描述类型默认值有效值重要性
listeners监听器列表 - 使用逗号分隔URI列表和监听器名称。如果侦听器名称不是安全协议,则还必须设置listener.security.protocol.map。指定主机名为0.0.0.0来绑定到所有接口。留空则绑定到默认接口上。合法监听器列表的示例:PLAINTEXT:// myhost:9092,SSL://:9091 CLIENT://0.0.0.0:9092,REPLICATION:// localhost:9093stringnull
advertised.listeners监听器发布到ZooKeeper供客户端使用,如果与listeners配置不同。在IaaS环境,这可能需要与broker绑定不通的接口。如果没有设置,将使用listeners的配置。与listeners不同的是,配置0.0.0.0元地址是无效的。stringnull
listener.security.protocol.map侦听器名称和安全协议之间的映射。必须定义为相同的安全协议可用于多个端口或IP。例如,即使两者都需要ssl,内部和外部流量也可以分开。具体的说,用户可以定义名字为INTERNAL和EXTERNAL的侦听器,这个属性为:internal:ssl,external:ssl。 如图所示,键和值由冒号分隔,映射条目以逗号分隔。 每个监听者名字只能在映射表上出现一次。 通过向配置名称添加规范化前缀(侦听器名称小写),可以为每个侦听器配置不同的安全性(ssl和sasl)设置。 例如,为内部监听器设置不同的密钥仓库,将会设置名称为“listener.name.internal.ssl.keystore.location”的配置。 如果没有设置侦听器名称的配置,配置将回退到通用配置(即ssl.keystore.location)。stringPLAINTEXT:PLAINTEXT,SSL:SSL,SASL_PLAINTEXT:SASL_PLAINTEXT,SASL_SSL:SASL_SSL
inter.broker.listener.namebroker间通讯的监听器名称。如果未设置,则侦听器名称由security.inter.broker.protocol定义。 同时设置此项和security.inter.broker.protocol属性是错误的,只设置一个。stringnull
security.inter.broker.protocolbroker之间的安全通讯协议,有效值有:PLAINTEXT, SSL, SASL_PLAINTEXT, SASL_SSL。同时设置此配置和inter.broker.listener.name属性会出错stringPLAINTEXT

简单解释

  • listeners : 监听器配置,通俗的说就是给kafka配置一个监听器,告诉外部连接者需要通过什么样的协议、什么样的地址、什么样的端口进行连接kafka broker
  • advertised_listeners: 这组监听器是 Broker 用于对外发布的,advertised_listeners 监听器会注册在 zookeeper 中。
    • 当我们对172.17.2.3:9092建立请求连接的时候,kafka broker会通过zk找到注册的INSIDE监听器,然后通过listeners找到对应的ip和端口 : 172.17.2.3:9092
    • 当我们对<公网 ip>:端口建立请求连接的时候,kafka broker会通过zk找到注册的OUTSIDE监听器,然后通过listeners找到对应的ip和端口: 172.17.2.3:9094
    • 更多关于listeners介绍:Kafka Listeners
listeners: INSIDE://172.17.2.3:9092,OUTSIDE://172.17.2.3:9094
advertised_listeners: INSIDE://172.17.2.3:9092,OUTSIDE://<公网 ip>:端口listener_security_protocol_map: "INSIDE:SASL_PLAINTEXT,OUTSIDE:SASL_PLAINTEXT"
inter_broker_listener_name: "INSIDE"
  • 1
  • 2
  • 3

DNS介绍

域名系统(服务)协议(DNS)是一种分布式网络目录服务,主要用于域名与 IP 地址的相互转换,以及控制因特网的电子邮件的发送

hostname

  • hostname即主机名字 , 每一个主机都会对应一个hostname, 在特定的网络范围内唯一
  • 每一个主机都会对应一个IP地址,在特定的网络范围内唯一

域名及域名解析

  • 域名是因特网范围内某一个服务器的名字,是用来解决IP地址不可读不好记的问题,例如百度的域名为 :baidu.com , 这个域名在响应的DNS服务中有对应的ip,当我们访问这个域名的时候会在先进行域名解析得到ip后在进行tcp/ip建立连接,具体的域名解析过程原理在此不赘述。
  • 专门用来进行域名解析的成为DNS服务器,DNS服务器根据范围不同分为互联网DNS服务器,局域网DNS服务器,当然对于每个主机而言在/etc/hosts配置ip地址和主机hostname的映射也可称为一个DNS服务器。

kafka中使用hostname(这是本篇文章的重点)

如上文所描述,kafka broker配置项listeners的作用和使用,listeners的地址配置不一定是ip, 也可以是hsotname:

listeners: INSIDE://my-hostname:9092,OUTSIDE://my-hostname:9094
advertised_listeners: INSIDE://my-hostname:9092,OUTSIDE://<my-out-hostname>:端口listener_security_protocol_map: "INSIDE:SASL_PLAINTEXT,OUTSIDE:SASL_PLAINTEXT"
inter_broker_listener_name: "INSIDE"
  • 1
  • 2
  • 3

如上所示,当advertised-listeners配置的地址为hostname的时候,外部客户端请求连接的时候是怎样的流程呢?
此时,我们如果直接访问ip进行请求连接是无法获取kafka broker中的数据的;当在主机的/etc/hosts文件中添加该hostname所映射的ip之后便可以请求kafka broker中的数据。

解释

  • 执行命令 kafka-topics --list --bootstrap-server ip:端口, kafka客户端会向broker请求kafka broker的所有元数据。 --bootstrap.servers实际上是引导地址,而不是客户端真正建立长链接的地址。也就是说,客户端会根据引导地址去broker询问集群的所有broker信息,拿到返回的broker服务信息之后,再向指定的broker发起链接请求。此时由于kafka borker的advertised_listeners配置的是hostname,那么返回给客户端的元信息中的地址也是hostname,当客户端准备根据这个hostname建立长连接请求数据的时候,发现并解析不了该hostname。 于是当在主机etc/hosts文件中添加该hostname的ip映射之后便会根据域名解析找到ip建立连接。
  • –bootstrap.servers是指向kafka broker的,如果使用–zookeeper便是向zk请求kafka broker的元数据了。

转载于 为什么kafka客户端需要配置 /etc/hosts文件__txg的博客-CSDN博客

  • host.name
    已弃用。 仅当listeners属性未配置时被使用,已用listeners属性代替。表示broker的hostnamejava

  • advertised.host.name
    已弃用。仅当advertised.listeners或者listeners属性未配置时被使用。官网建议使用advertised.listeners。该配置的意思是这册到zookeeper上的broker的hostname或ip。是提供给客户端与kafka通讯使用的。若是没有设置则使用host.nameweb

  • listeners
    须要监听的URL和协议,如:PLAINTEXT://myhost:9092,SSL://:9091 CLIENT://0.0.0.0:9092,REPLICATION://localhost:9093。若是未指定该配置,则使用java.net.InetAddress.getCanonicalHostName()函数的的返回值bootstrap

  • advertised.listeners
    注册到zookeeper上并提供给客户端的监听器,若是没有配置则使用listeners。若是listeners也没有配置则使用java.net.InetAddress.getCanonicalHostName()函数的的返回值ruby

从上诉配置咱们很清楚的了解了该如何配置hostname,可是咱们如何把外网ip注册到zookeeper呢,答案是不可能的,由于内网是不识别外网ip的。服务器

网上一些道友的解决方法以下:svg

<span style="background-color:#f8f8ff"><span style="color:#000000">advertised<span style="color:#999999"><strong>.listeners</strong></span>=PLAINTEXT<span style="color:#990073">://</span><span style="color:#0086b3"><span style="color:#990073">x</span></span><span style="color:#999999"><strong>.x</strong></span><span style="color:#999999"><strong>.x</strong></span><span style="color:#999999"><strong>.<span style="color:#990073">x</span></strong></span><span style="color:#990073">:</span><span style="color:#40a070"><span style="color:#40a070">9092</span></span></span></span>

x.x.x.x为外网ip。
想法很丰满,直接把外网ip注册给zookeeper,这样客户端就能够识别到外网ip进行访问了。但现实很骨感,内网是不识别外网ip的,这样把外网ip配置进去,不报错才怪。函数

解决方案

一、修改server.properties配置文件ui

<span style="background-color:#f8f8ff"><span style="color:#000000">advertised.listeners=PLAINTEXT<span style="color:#990073"><span style="color:#990073">://kafka1</span></span><span style="color:#990073"><span style="color:#990073">:</span></span><span style="color:#40a070"><span style="color:#40a070">9092</span></span></span></span>

二、修改aws上broker的/etc/hosts文件

<span style="background-color:#f8f8ff"><span style="color:#000000">[内网ip]    <span style="color:#000080"><span style="color:#000080">kafka1</span></span></span></span>

三、修改外网访问服务器上的/etc/hosts文件

<span style="background-color:#f8f8ff"><span style="color:#000000">[外网ip]    <span style="color:#000080"><span style="color:#000080">kafka1</span></span></span></span>

这样外部生产/消费的时候只要指定kafka1,就能够进行访问了。

<span style="background-color:#f8f8ff"><span style="color:#000000">props<span style="color:#999999"><strong>.put</strong></span>(<span style="color:#219161"><span style="color:#219161">"bootstrap.servers"</span></span>, <span style="color:#219161"><span style="color:#219161">"kafka1:9092"</span></span>)<span style="color:#408080"><em>;</em></span></span></span>
  • 4
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
Filebeat可以将数据直接发送到Kafka,可以使用以下步骤配置Filebeat将数据发送到Kafka: 1. 下载和安装Filebeat 参考前面我给你的答案,下载和安装Filebeat。 2. 配置Filebeat 在Filebeat的配置文件中(filebeat.yml),添加以下配置,将数据发送到Kafka: ``` output.kafka: hosts: ["kafka-broker1:9092", "kafka-broker2:9092"] topic: "my-topic" required_acks: 1 compression: gzip max_message_bytes: 1000000 partition.round_robin: reachable_only: false version: "2.1.1" ``` 说明: - hosts: 指定Kafka的broker地址。 - topic: 指定发送到的Kafka主题。 - required_acks: 指定Kafka需要确认的acks数。如果设置为1,则需要Kafka确认写入成功;如果设置为0,则不需要确认写入成功;如果设置为-1,则需要Kafka确认所有副本已经写入成功。 - compression: 指定压缩算法。默认为none,可选的值包括none、gzip和snappy。 - max_message_bytes: 指定每条消息的最大字节数。默认为1000000。 - partition.round_robin: 指定使用round-robin方式将消息发送到分区。 - version: 指定Kafka协议版本。 3. 启动Filebeat 启动Filebeat服务,Filebeat将开始将数据发送到Kafka。 ``` PS > Start-Service filebeat ``` 4. 测试 发送一些测试数据,检查数据是否已经成功发送到Kafka中的指定主题。 ``` echo "Hello, Kafka!" | .\filebeat -e -c .\filebeat.yml -d "publish" ``` 注意:在测试时需要将filebeat.yml中的path配置项修改为实际的日志文件路径。 以上就是使用Filebeat将数据发送到Kafka的步骤。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值