Kafka 服务器配置 - 侦听器与adverted.listeners

Posted

技术标签:

【中文标题】Kafka 服务器配置 - 侦听器与adverted.listeners【英文标题】:Kafka server configuration - listeners vs. advertised.listeners 【发布时间】:2017-08-17 08:29:49 【问题描述】:

要让 Kafka 运行,您需要在 config/server.properties 文件中设置一些属性。有两个设置我不明白。

有人可以解释 listeners 和 Advertisementd.listeners 属性之间的区别吗?

文档说:

listeners:套接字服务器监听的地址。

advertised.listeners: 代理将向生产者和消费者通告主机名和端口。

我什么时候必须使用哪个设置?

【问题讨论】:

【参考方案1】:

listeners 是代理将用来创建服务器套接字的。

advertised.listeners 是客户端用来连接代理的。

如果您有一个“复杂”的网络设置(例如公共子网和私有子网以及中间的路由),这两个设置可能会有所不同。

【讨论】:

【参考方案2】:

来自这个链接:https://cwiki.apache.org/confluence/display/KAFKA/KIP-103%3A+Separation+of+Internal+and+External+traffic

在 0.9.0.0 发布周期内,每个版本支持多个侦听器 经纪人介绍。每个侦听器都与一个安全相关联 协议、IP/主机和端口。当与广告相结合时 监听器机制,有一个相当大的灵活性 限制:每个安全协议中最多有一个侦听器 两个配置(listeners 和adverted.listeners)。

在某些环境中,可能需要区分外部 客户端、内部客户端和复制流量独立于 出于成本、性能和安全原因的安全协议。一些 说明这一点的例子:

复制流量被分配到一个单独的网络接口,这样它就不会干扰客户端流量。 外部流量通过代理/负载平衡器(安全性、灵活性),而内部流量直接到达代理 (性能、成本)。 即使安全协议相同,外部流量和内部流量的安全设置也不同(例如,不同的一组 启用 SASL 机制、身份验证服务器、不同的密钥库、 等)

因此,我们建议 Kafka 代理应该能够定义 用于绑定的相同安全协议的多个侦听器(即 听众)和共享(即adverted.listeners),以便内部, 如果需要,可以将外部流量和复制流量分开。

所以,

listeners - 我们将监听的以逗号分隔的 URI 列表及其协议。 将主机名指定为0.0.0.0 以绑定到所有接口。 将主机名留空以绑定到默认接口。 合法监听器列表示例:

PLAINTEXT://myhost:9092,TRACE://:9091 PLAINTEXT://0.0.0.0:9092, TRACE://localhost:9093

advertised.listeners - 发布到 ZooKeeper 以供客户端使用的侦听器,如果与上面的侦听器不同。 在 IaaS 环境中,这可能需要与代理绑定的接口不同。如果未设置,将使用 listeners 的值。

【讨论】:

【参考方案3】:

由于我还不能发表评论,所以我会将其作为“答案”发布,并添加到 M.Situations 答案中。

在他链接的同一个文档中,有一个关于 KAFKA 客户端 (https://cwiki.apache.org/confluence/display/KAFKA/KIP-103%3A+Separation+of+Internal+and+External+traffic) 使用哪个侦听器的简介:

如前所述,客户端永远不会看到侦听器名称,并且会像以前一样发出元数据请求。不同之处在于它们返回的端点列表仅限于它们发出请求的端点的侦听器名称。

这很重要,因为这取决于您在 bootstrap.servers 配置中使用的 URL*,如果它被映射到 ads.listeners 中,客户端将返回的 URL*(如果监听器不知道行为是什么)不存在)。

还要注意这一点:

例外是基于 ZooKeeper 的消费者。这些消费者直接从 ZooKeeper 检索代理注册信息,并将选择第一个使用 PLAINTEXT 作为安全协议(它们支持的唯一安全协议)的侦听器。

作为一个示例代理配置(适用于集群中的所有代理):

advertised.listeners=EXTERNAL://XXXXX.compute-1.amazonaws.com:9990,INTERNAL://ip-XXXXX.ec2.internal:9993

inter.broker.listener.name=内部

listener.security.protocol.map=EXTERNAL:SSL,INTERNAL:PLAINTEXT

如果客户端使用 XXXXX.compute-1.amazonaws.com:9990 进行连接,则元数据提取将转到该代理。但是,与 Group Coordinator 或 Leader 一起使用的返回 URL 可能是 123.compute-1.amazonaws.com:9990*(不同的机器!)。这意味着匹配是在 KIP-103 所宣传的侦听器名称上完成的,而与实际 URL(节点)无关。

由于 EXTERNAL 的协议映射是 SSL,这将迫使您使用 SSL 密钥库进行连接。

另一方面,如果您在 AWS 中,那么您可以发出 ip-XXXXX.ec2.internal:9993 并且根据协议映射,相应的连接将是明文。

这在 IaaS 中尤其需要,在我的案例中,代理和消费者位于 AWS 上,而我的生产者位于客户端站点上,因此需要不同的安全协议和侦听器。

编辑: 由于您为不同的客户端(代理、生产者、消费者)提供了不同的端口,因此添加入站规则也变得更加容易。

编辑2: 如果以上内容还不清楚,这篇文章是一个很好的深度指南:https://rmoff.net/2018/08/02/kafka-listeners-explained/

【讨论】:

我不确定您是否可以同时为listenersadvertised.listeners 分配别名,至少对我来说,在 HDP 2.5.0.3 上它不起作用,也许错过了一些东西。对我有用的是定义不同的配置组并在所需的 IP 地址上设置特定的广告。谢谢, @reim 非常感谢您提到Config Groups,因为需要为每个代理分别配置advertised.listeners(总共3个代理)。在我使用 AWS 时,advertised.listeners 对我来说是强制性的。 EDIT2:收听消息不起作用,只能获取元数据:docker-compose exec kafkacat kafkacat -b kafka1:29092 -t Topic(注意缺少-L 部分) config/server.properties 中提到 EC2 Public IPv4 DNSadvertised.listeners 提供荣誉【参考方案4】:

在此处为该问题提供的答案中存在太多混乱或信息很少。因此,为了清楚起见,发布我精心制作的答案。

    listeners - 由 kafka 中的嵌入式 jetty Web 服务器用于绑定。该码头 Web 服务器用于提供 REST API,为 Kafka Connect 工作人员提供控制平面。如果您希望 kafka 绑定到 localhost,则此设置中的主机名可以留空(通过调用 InetAddress.getLocalHost().getCanonicalHostName() java api 来实现) advertised.listeners:这个地址被每个kafka broker发布给zookeeper。如果未设置此设置,则此处将使用 listeners 的值并发布到 zookeeper。这是此设置通知他人的唯一目的。 Kafka 客户端使用发布到 zookeeper(/brokers/ids/<id>/ # endpoints)的“advertised.listeners”设置与 Kafka 代理对话。

现在的问题是为什么要有两个设置?为什么不是单一设置?假设您的 kafka 经纪人坐在代理后面。所有的 kafka 客户端都必须与代理交谈才能联系到代理。在这种情况下,我们希望 kafka 的嵌入式码头服务器绑定到 localhost 和本地端口,但我们无法将其发布到 zookeeper,因为客户端无法使用它。所以kafka admin可以将advertised.listeners设置为代理主机和端口。

另外,在我们的一些生产主机中,InetAddress.getLocalHost().getCanonicalHostName() 返回空,因此侦听器设置的主机名是空的,这对于码头绑定来说很好。但是adverted.listeners 以NULL:9092 的形式发布到zookeeper,因为默认情况下它采用与侦听器相同的值。现在所有代理都试图以这种方式发布到 Zookeeper,所以代理收到错误 java.lang.IllegalArgumentException: requirement failed: Configured end points null:14092 as advertised.listeners 因为 NULL:9092 已由代理 101 注册。解决方法是将 advertised.listeners 设置更改为包含主机名它。

【讨论】:

以上是关于Kafka 服务器配置 - 侦听器与adverted.listeners的主要内容,如果未能解决你的问题,请参考以下文章

Kubernetes 多节点上的 Kafka

使用 application.yml/properties 的批处理侦听器的 Spring kafka 集成属性

Java自学!spring-kafka监听器不好使

Kafka - 在 Linux 和 Windows 之间创建代理侦听器时出错

Kafka 监听器详解

Spring Boot Kafka监听器不一致