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

CPA*_*CPA 40 amazon-ec2 apache-kafka

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

有人可以解释一下监听器和advertised.listeners属性之间的区别吗?

文件说:

listeners:套接字服务器侦听的地址.

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

我何时必须使用哪种设置?

Pra*_*mer 31

由于我无法发表评论,我会将其作为"答案"发布,并添加到M.Situations的答案中.

在他链接的同一文档中,有一个关于KAFKA客户端使用哪个监听器的模糊(https://cwiki.apache.org/confluence/display/KAFKA/KIP-103%3A+Separation+of+Internal+and+外部+流量):

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

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

另请注意:

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

作为示例代理配置(对于集群中的所有代理):

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

inter.broker.listener.name = INTERNAL

listener.security.protocol.map = EXTERNAL:SSL,内部:PLAINTEXT

如果客户端使用XXXXX.compute-1.amazonaws.com:9990进行连接,则元数据提取将转到该代理.但是,与组协调员或领导者一起使用的返回URL可以是123.compute-1.amazonaws.com:9990*(另一台机器!).这意味着匹配是在KIP-103公布的侦听器名称上完成的,而与实际的URL(节点)无关.

由于EXTERNAL的协议映射是SSL,因此会强制您使用SSL密钥库进行连接.

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

这在IaaS中尤其需要,在我的案例中,经纪人和消费者都在AWS上,而我的生产者则生活在客户端站点上,因此需要不同的安全协议和监听器.

编辑:由于您为不同的客户(经纪人,生产者,消费者)提供了不同的端口,因此添加入站规则要容易得多.


Thi*_*ilo 23

listeners 是代理将用于创建服务器套接字的内容.

advertised.listeners 是客户将用于连接经纪人的东西.

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

  • 你好。我理解正确吗?- **Listeners** - 只是您想要保留的“主机:端口”列表。就像启动开发服务器一样,服务器进程会将自身(保留)绑定到“主机:端口”(localhost:3000 fe)。- **Advertized.listeners** - 可用于从某处访问代理的 `ad_host:port` 列表。它不一定是互联网。要点是`ad_host:port`需要从生产者/监听器运行的地方和**kafka启动的地方**可访问**(比如容器)。因为代理会在启动时 ping `ad_host`。 (2认同)

Tho*_*Tho 18

Listeners是 Kafka 代理侦听的所有地址(可以超过 1 个地址),而advertised listeners其他代理(生产者、消费者或代理)想要与当前代理对话时需要连接的地址。

\n

localhost:9092如果所有列表都在同一台计算机上运行(可以使用或连接),则这两个列表应该相同,127.0.0.1:9092但如果消费者、生产者或其他代理不在同一台计算机或 Docker 实例上,则它们必须使用不同的地址(即\'这就是为什么我们有advertised listeners)。两个例子:

\n
    \n
  • 假设我们使用 Docker 运行 2 个名为kafka和 的Kafka 实例kafka2kafka2肯定无法连接到kafka使用localhost:29092。必须用它kafka:9092来代替。因此对于kafka, 侦听器 = localhost:29092, 广告侦听器 =kafka:9092
  • \n
  • 主机上的生产者无法kafka使用kafka:9092. 必须用它localhost:29092来代替。
  • \n
\n

让我们使用以下docker-compose配置来了解有关 Kafka Broker 的启动过程的更多信息:

\n
# config/docker-compose.yml\n  kafka:\n    image: docker.io/bitnami/kafka:3\n    ports:\n      - "29092:29092"\n      - "9092:9092"\n    environment:\n      - KAFKA_CFG_ZOOKEEPER_CONNECT=zookeeper:2181\n      - ALLOW_PLAINTEXT_LISTENER=yes\n      - KAFKA_CFG_LISTENER_SECURITY_PROTOCOL_MAP=CLIENT:PLAINTEXT,EXTERNAL:PLAINTEXT\n      - KAFKA_CFG_LISTENERS=CLIENT://:9092,EXTERNAL://:29092\n      - KAFKA_CFG_ADVERTISED_LISTENERS=CLIENT://kafka:9092,EXTERNAL://localhost:29092\n      - KAFKA_CFG_INTER_BROKER_LISTENER_NAME=CLIENT\n    depends_on:\n      - zookeeper\n
Run Code Online (Sandbox Code Playgroud)\n

通过此配置,Docker 将启动 1 个 Kafka 代理实例,该实例侦听 2 个端口:

\n
    \n
  • 9092有名字CLIENT
  • \n
  • 29092有名字EXTERNAL
  • \n
\n

然后,代理连接到 Zookeeperzookeeper:2181并注册其 2 个地址:kafka:9092localhost:29092。此外,对于KAFKA_CFG_INTER_BROKER_LISTENER_NAME=CLIENT,它希望 Zookeeper 告诉其他代理kafka:9092如果想与它交谈就连接到它。

\n

但为什么需要 2 个端口呢?在这里阅读更多内容

\n

参考:

\n\n


vij*_*iji 15

此处针对该问题提供的答案中有太多混乱或信息很少。因此,为了清楚起见,发布我详细的答案。

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

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

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


Max*_*nga 5

通过此链接:https : //cwiki.apache.org/confluence/display/KAFKA/KIP-103%3A+Separation+of+Internal+and+External+traffic

在0.9.0.0发布周期中,引入了对每个代理支持多个侦听器的支持。每个侦听器都与安全协议,ip /主机和端口相关联。与通告的侦听器机制结合使用时,存在相当大的灵活性,但有一个限制:两个配置(侦听器和advertised.listeners)中的每个配置中,每个安全协议最多有一个侦听器。

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

  • 复制流量被分配给单独的网络接口,以使其不会干扰客户端流量。
  • 外部流量通过代理/负载平衡器(安全性,灵活性),而内部流量则直接对代理(性能,成本)产生影响。
  • 即使安全协议相同,外部和内部流量的安全设置也不同(例如,启用的SASL机制,身份验证服务器,不同的密钥库等的不同集合)

因此,我们建议Kafka代理应该能够为同一安全协议定义多个侦听器,以进行绑定(即侦听器)和共享(即advertised.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将使用的值。