Heim >Backend-Entwicklung >Golang >Stellen Sie eine Verbindung zu Kafka her, das in Docker ausgeführt wird
Im heutigen Bereich der Softwareentwicklung ist die Containerisierungstechnologie zu einer immer beliebter werdenden Bereitstellungsmethode geworden. Als eine der beliebtesten Containerisierungslösungen bietet Docker Entwicklern praktische Methoden zur Isolierung und Bereitstellung von Umgebungen. Für Entwickler, die Kafka als Nachrichtenwarteschlangensystem verwenden, kann die Kombination von Kafka mit Docker die Entwicklung und Bereitstellung flexibler und effizienter machen. In diesem Artikel stellt der PHP-Editor Xigua vor, wie man Kafka in Docker ausführt, damit Sie den Komfort der Containerisierung problemlos nutzen können.
Ich habe auf meinem lokalen Computer einen Kafka-Docker-Container mit einem Knoten eingerichtet, wie in der Confluence-Dokumentation beschrieben (Schritte 2-3).
Außerdem habe ich den Port 2181 von zookeeper und den Port 9092 von kafka offengelegt, sodass ich von einem Client, der auf meinem lokalen Computer ausgeführt wird, eine Verbindung zu ihnen herstellen kann:
$ docker run -d \ -p 2181:2181 \ --net=confluent \ --name=zookeeper \ -e zookeeper_client_port=2181 \ confluentinc/cp-zookeeper:4.1.0 $ docker run -d \ --net=confluent \ --name=kafka \ -p 9092:9092 \ -e kafka_zookeeper_connect=zookeeper:2181 \ -e kafka_advertised_listeners=plaintext://kafka:9092 \ -e kafka_offsets_topic_replication_factor=1 \ confluentinc/cp-kafka:4.1.0
Problem: Wenn ich versuche, vom Host aus eine Verbindung zu Kafka herzustellen, schlägt die Verbindung fehl, weil 无法解析地址:kafka:9092
.
Das ist mein Java-Code:
properties props = new properties(); props.put("bootstrap.servers", "localhost:9092"); props.put("client.id", "kafkaexampleproducer"); props.put("key.serializer", longserializer.class.getname()); props.put("value.serializer", stringserializer.class.getname()); kafkaproducer<long, string> producer = new kafkaproducer<>(props); producerrecord<long, string> record = new producerrecord<>("foo", 1l, "test 1"); producer.send(record).get(); producer.flush();
Ausnahmen:
java.io.IOException: Can't resolve address: kafka:9092 at org.apache.kafka.common.network.Selector.doConnect(Selector.java:235) ~[kafka-clients-2.0.0.jar:na] at org.apache.kafka.common.network.Selector.connect(Selector.java:214) ~[kafka-clients-2.0.0.jar:na] at org.apache.kafka.clients.NetworkClient.initiateConnect(NetworkClient.java:864) [kafka-clients-2.0.0.jar:na] at org.apache.kafka.clients.NetworkClient.ready(NetworkClient.java:265) [kafka-clients-2.0.0.jar:na] at org.apache.kafka.clients.producer.internals.Sender.sendProducerData(Sender.java:266) [kafka-clients-2.0.0.jar:na] at org.apache.kafka.clients.producer.internals.Sender.run(Sender.java:238) [kafka-clients-2.0.0.jar:na] at org.apache.kafka.clients.producer.internals.Sender.run(Sender.java:176) [kafka-clients-2.0.0.jar:na] at java.lang.Thread.run(Thread.java:748) [na:1.8.0_144] Caused by: java.nio.channels.UnresolvedAddressException: null at sun.nio.ch.Net.checkAddress(Net.java:101) ~[na:1.8.0_144] at sun.nio.ch.SocketChannelImpl.connect(SocketChannelImpl.java:622) ~[na:1.8.0_144] at org.apache.kafka.common.network.Selector.doConnect(Selector.java:233) ~[kafka-clients-2.0.0.jar:na] ... 7 common frames omitted
Frage: Wie verbinde ich mich mit Kafka, das im Docker läuft? Mein Code wird vom Host ausgeführt, nicht vom Docker.
Hinweis: Ich weiß, theoretisch könnte ich DNS-Einstellungen ausprobieren und /etc/hosts
, aber das ist eine Problemumgehung – so sollte es nicht sein.
Hier gibt es eine ähnliche Frage, aber sie basiert auf dem ches/kafka
-Bild. Ich verwende Bilder basierend auf confluenceinc
und das ist anders. ches/kafka
图像。我使用基于 confluenceinc
的图像,这是不一样的。
tl;dr - 从容器到主机的简单端口转发将不起作用...主机文件(例如 *NIX 系统上的 /etc/hosts
advertished.listeners
(不是 advertished.host.name
和 advertished.port
,因为这些已被弃用)。如果您看到诸如 Connection to node -1 (localhost/127.0.0.1:9092)
– Eine einfache Portweiterleitung vom Container zum Host wird bootstrap.servers
一部分列出的服务器实际上是可解析的。例如 ping
IP/主机名,使用 netcat
检查端口...如果您的客户端位于容器中,则需要从容器执行此操作,而不是(仅)从主机执行此操作。如果容器没有立即崩溃以访问其 shell,请使用 docker exec
nicht funktionieren
auf *NIX-Systemen) sollten nicht geändert werden, um Kafka-Netzwerkprobleme zu beheben, da dies bei dieser Lösung nicht der Fall ist tragbar. docker ps
显示 kafka 容器是从 0.0.0.0 映射的:50c5a3c9bd6141bda139d1e2f6e9d778 -> cd3356af2f6e059e7bd54cd1ababa980 /tcp
eingestellt ist. Ein Fehler wie confluenceinc
docker 镜像来解决所提出的问题,不是 wurstmeister/kafka
。如果您设置了 KAFKA_ADVERTISED_HOST_NAME
bedeutet, dass Ihr Anwendungscontainer versucht, eine Verbindung zu sich selbst herzustellen. Führen Ihre Anwendungscontainer auch Kafka-Brokerprozesse aus? vielleicht nicht.
2) Stellen Sie sicher, dass .
3) Um zu überprüfen, ob die Ports korrekt auf dem Host zugeordnet sind, wenn Sie den Prozess vom Host statt von einem anderen Container ausführen, stellen Sie sicher, dass beim Versuch, den Client von außerhalb des Docker-Netzwerks auszuführen, übereinstimmen müssen. Keine Portweiterleitung zwischen zwei Containern erforderlich; Link-/Docker-Netzwerk verwenden
Die Antwort unten verwendet das Docker-Image confluenceinc
, um das gestellte Problem zu lösen, nicht . Wenn Sie die Variable KAFKA_ADVERTISED_HOST_NAME
festlegen, entfernen Sie sie bitte (es handelt sich um eine veraltete Eigenschaft)
wurstmeister/kafka
laufen alle in Containern Kafka
.Sie verlassen sich nur darauf, wie es konfiguriert ist a>. Und welche Variablen dies verursachen.
bitnami/kafka
Ab Oktober 2023 ist dieser Inhalt nicht mehr in DockerHub vorhanden. Auf jeden Fall wird es nach 2022 nicht mehr aufrechterhalten. wurstmeister
Lesen Sie den Readme-Abschnitt zur
debezium/kafka
. HINWEIS: Veröffentlichte Host- und Porteinstellungen sind veraltet. Werbung Listeners deckt beides ab. Ähnlich wie der Confluence-Container kann Debezium seine Eigenschaften mithilfe der vorangestellten Proxy-Einstellungen aktualisieren. KAFKA_
ubuntu/kafka
要求您通过 Docker 映像参数添加 --overrideadvertising.listeners=kafka:9092
spotify/kafka
fast-data-dev
或 lensesio/box
nur Kafka wollen. Außerdem handelt es sich hierbei um ein Docker-Anti-Pattern zum Ausführen mehrerer Dienste in einem Container
Dockerfile
voll funktionsfähig und Netzwerkdiagramme finden Sie unter docker-compose
Dieser Blog wurde geschrieben von: @rmoff
Confluence Quick Start (Docker)-Dokumentation geht davon aus, dass alle Produktions- und Verbrauchsanforderungen innerhalb des Docker-Netzwerks erfolgen.
Sie können das Problem der Verbindung mit umgehen, indem Sie den Kafka-Clientcode in einem eigenen Container ausführen (mithilfe einer Docker-Bridge). Andernfalls müssen Sie jedoch weitere Umgebungsvariablen hinzufügen, um den Container nach außen hin verfügbar zu machen, während er noch vorhanden ist innerhalb von Docker Arbeiten im Netzwerk. kafka:9092
hinzu, die das Listener-Protokoll dem Kafka-Protokoll zuordnetPLAINTEXT_HOST:PLAINTEXT
KAFKA_LISTENER_SECURITY_PROTOCOL_MAP
Wert: PLAINTEXT:PLAINTEXT,PLAINTEXT_HOST:PLAINTEXT
hier, also überprüfen Sie noch einmal Ihren Dienst + Hostnamen). kafka
指的是 docker 容器名称;它也可能被命名为 broker
KAFKA_ADVERTISED_LISTENERS
Wert: PLAINTEXT://kafka:9092,PLAINTEXT_HOST://localhost:29092
Bitte beachten Sie, dass das Protokoll hier mit dem Wert links in der Protokollzuordnungseinstellung oben übereinstimmt
Fügen Sie beim Ausführen des Containers einen-Listener hinzu. -p 29092:29092
进行主机端口映射,并通告 PLAINTEXT_HOST
mit den oben genannten Einstellungen)
Wenn immer noch nicht funktioniert, können Sie ändern wobei beide Optionen mit den Anzeigeneinstellungen und den von Docker weitergeleiteten Ports übereinstimmen KAFKA_LISTENERS
设置为包含 9625b882931466931ca10eb1a60367b3://0.0.0.0:a3b0c87895079be75e30be94102cc20b
Mit anderen Worten: Wenn Sie einen Kafka-Client (einschließlich CLI-Tools, die Sie möglicherweise lokal installiert haben) außerhalb eines Docker-Netzwerks ausführen, verwenden Sie
als Zookeeper (erfordert Docker-Portweiterleitung) localhost:29092
作为引导服务器,使用 localhost:2181
) 192.168.x.y
sowie/anstelle von localhost angeben.
Das einfache Ankündigen von localhost über die Portweiterleitung funktioniert nicht, da das Kafka-Protokoll weiterhin Ihre konfigurierten Listener ankündigt.
und Router-Portweiterleitung (und Firewall-/Sicherheitsgruppenänderungen), wenn sich Ihr Container nicht im selben lokalen Netzwerk befindet, z. B. wenn Ihr Container in der Cloud ausgeführt wird und Sie von Ihrem lokalen Computer aus mit ihm interagieren möchten.
Client (oder ein anderer Proxy) in einem Container auf demselben HostWenn Sie die Anwendung
in einem Docker-Netzwerk ausführen, verwenden Sie (siehe die oben angegebene Listener-Konfiguration PLAINTEXT
) als Bootstrap-Server und zookeeper:2181
als Zookeeper wie jede andere Docker-Dienstkommunikation (ohne erforderliche Portweiterleitung) kafka:9092
(请参阅上面广告的 PLAINTEXT
侦听器配置)作为引导服务器,使用 zookeeper:2181
docker run
命令或 Compose 文件,则需要使用 compose networks
部分或 docker network --create
手动定义共享 network
verwenden
Sehen Sie sich die Compose-Beispieldatei für den vollständigen Confluence-Stack an oder für eine einfachere Version für einen einzelnen Broker.
Wenn Sie mehrere Proxys verwenden, müssen diese einen eindeutigen Hostnamen und einen Anzeigen-Listener verwenden. Beispiel ansehen一个>
Verbinden Sie sich über Docker (ksqlDB) mit Kafka auf dem Host
Für alle, die sich für die Bereitstellung von Kubernetes interessieren:
Das obige ist der detaillierte Inhalt vonStellen Sie eine Verbindung zu Kafka her, das in Docker ausgeführt wird. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!