Rumah  >  Artikel  >  pembangunan bahagian belakang  >  Sambung ke Kafka berjalan di Docker

Sambung ke Kafka berjalan di Docker

PHPz
PHPzke hadapan
2024-02-14 23:42:08951semak imbas

连接到在 Docker 中运行的 Kafka

Dalam bidang pembangunan perisian hari ini, teknologi kontena telah menjadi kaedah penggunaan yang semakin popular. Sebagai salah satu penyelesaian kontena yang paling popular, Docker menyediakan pembangun dengan kaedah pengasingan dan penggunaan persekitaran yang mudah. Bagi pembangun yang menggunakan Kafka sebagai sistem baris gilir mesej, menggabungkan Kafka dengan Docker boleh menjadikan pembangunan dan penggunaan lebih fleksibel dan cekap. Dalam artikel ini, editor PHP Xigua akan memperkenalkan cara menjalankan Kafka dalam Docker, supaya anda boleh dengan mudah menikmati kemudahan yang dibawa oleh kontena.

Kandungan soalan

Saya menyediakan bekas docker kafka nod tunggal pada mesin tempatan saya seperti yang diterangkan dalam dokumentasi pertemuan (langkah 2-3).

Selain itu, saya mendedahkan port zookeeper 2181 dan port kafka 9092 supaya saya boleh menyambung kepada mereka daripada pelanggan yang dijalankan pada mesin tempatan saya:

$ 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

Masalah: Apabila saya cuba menyambung ke kafka dari hos, sambungan gagal kerana 无法解析地址:kafka:9092.

Ini kod java saya:

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();

Pengecualian:

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

Soalan: Bagaimana untuk menyambung ke kafka berjalan di docker? Kod saya dijalankan daripada hos, bukan docker.

Nota: Saya tahu secara teori saya boleh mencuba tetapan dns dan /etc/hosts tetapi ini adalah penyelesaian - ia tidak sepatutnya seperti ini.

Terdapat soalan yang sama di sini, tetapi ia berdasarkan imej ches/kafka. Saya menggunakan imej berdasarkan confluenceinc dan ini berbeza. ches/kafka 图像。我使用基于 confluenceinc 的图像,这是不一样的。

解决方法

tl;dr - 从容器到主机的简单端口转发将不起作用...主机文件(例如 *NIX 系统上的 /etc/hosts

Penyelesaian

advertished.listeners (不是 advertished.host.nameadvertished.port,因为这些已被弃用)。如果您看到诸如 Connection to node -1 (localhost/127.0.0.1:9092)

tl;dr

- Pemajuan port mudah dari bekas ke hos akan bootstrap.servers 一部分列出的服务器实际上是可解析的。例如 ping IP/主机名,使用 netcat 检查端口...如果您的客户端位于容器中,则需要从容器执行此操作,而不是(仅)从主机执行此操作。如果容器没有立即崩溃以访问其 shell,请使用 docker exectidak berfungsi

... Fail hos (cth.

pada *sistem NIX) tidak boleh diubah suai untuk menyelesaikan isu rangkaian Kafka kerana Penyelesaian ini bukan mudah alih. docker ps 显示 kafka 容器是从 0.0.0.0 映射的:50c5a3c9bd6141bda139d1e2f6e9d778 -> cd3356af2f6e059e7bd54cd1ababa980 /tcp

1) IP/nama hos + port sebenar yang manakah anda ingin sambungkan? Pastikan nilai ditetapkan kepada

pada proksi Ralat seperti confluenceinc docker 镜像来解决所提出的问题,不是 wurstmeister/kafka。如果您设置了 KAFKA_ADVERTISED_HOST_NAME bermakna bekas aplikasi anda cuba disambungkan kepada dirinya sendiri. Adakah bekas aplikasi anda juga menjalankan proses broker Kafka? Mungkin tidak.

2) Pastikan sebagai . 3) Untuk mengesahkan bahawa port dipetakan dengan betul pada hos jika menjalankan proses daripada hos dan bukannya bekas lain, pastikan Jika cuba menjalankan klien dari luar rangkaian Docker, port mesti sepadan. Tiada penghantaran port diperlukan antara dua bekas;
Jawapan di bawah menggunakan imej docker confluenceinc untuk menyelesaikan masalah yang ditimbulkan, bukan . Jika anda menetapkan pembolehubah KAFKA_ADVERTISED_HOST_NAME, sila alih keluarnya (ia adalah harta yang tidak digunakan lagi)

Bahagian berikut cuba meringkaskan semua butiran yang diperlukan untuk menggunakan imej lain. Untuk imej Kafka lain yang biasa digunakan,

semuanya berjalan dalam bekas wurstmeister/kafkaApache

Kafka

.

Anda hanya bergantung pada

cara ia dikonfigurasikan. Dan a>pembolehubah manakah yang menyebabkan ini.

bitnami/kafka

Sehingga Oktober 2023, kandungan ini tidak lagi wujud dalam DockerHub. Walau apa pun, ia tidak akan dikekalkan selepas 2022.

wurstmeisterLihat bahagian readme pada konfigurasi pendengar, dan juga

baca wiki Ketersambungan mereka

. debezium/kafka

Jika anda mahukan bekas kecil, cuba yang ini. Imej jauh lebih kecil daripada Confluence dan lebih baik diselenggara daripada

. 🎜Rujuk fail readme mereka untuk konfigurasi pendengar🎜. 🎜 🎜🎜🎜 Dokumentasi yang berkaitan disebut 🎜di sini🎜di sini🎜. 🎜

NOTA: Tetapan hos dan port yang diterbitkan telah ditamatkan. Iklan Pendengarmerangkumi kedua-duanya. Sama seperti bekas Confluence, Debezium boleh mengemas kini sifatnya menggunakan tetapan proksi yang diawali dengan KAFKA_.

Lain-lain

  • ubuntu/kafka 要求您通过 Docker 映像参数添加 --overrideadvertising.listeners=kafka:9092...Saya mendapati ia kurang mudah alih berbanding pembolehubah persekitaran dan tidak mengesyorkannya
  • spotify/kafka Lapuk dan usang.
  • fast-data-devlensesio/box Bagus untuk penyelesaian semua-dalam-satu, dengan pendaftaran skema, Kafka Connect, dll., tetapi kembung jika anda sahaja mahukan Kafka. Selain itu, ini ialah corak anti Docker untuk menjalankan berbilang perkhidmatan dalam bekas
  • Anda sendiri Dockerfile - Mengapa? Adakah perkara lain ini tidak lengkap? Mulakan dengan permintaan tarik dan bukannya bermula dari awal.

Untuk bacaan tambahan, berfungsi sepenuhnya docker-compose dan rajah rangkaian, sila lihat Blog ini ditulis oleh: @rmoff

Jawapan

Dokumentasi

Confluence Quick Start (Docker) mengandaikan bahawa semua permintaan pengeluaran dan penggunaan akan berlaku dalam rangkaian Docker.

Anda boleh menyelesaikan masalah menyambung ke kafka:9092 dengan menjalankan kod klien Kafka dalam bekasnya sendiri (menggunakan jambatan Docker), tetapi jika tidak, anda perlu menambah lebih banyak pembolehubah persekitaran untuk mendedahkan bekas ke luar sambil tetap membiarkannya dijalankan di bawah Docker Work dalam rangkaian.

Mula-mula tambahkan pemetaan protokol PLAINTEXT_HOST:PLAINTEXT yang memetakan protokol pendengar kepada protokol Kafka

Kunci: KAFKA_LISTENER_SECURITY_PROTOCOL_MAP
Nilai: PLAINTEXT:PLAINTEXT,PLAINTEXT_HOST:PLAINTEXT

Kemudian sediakan dua pendengar yang diiklankan pada port yang berbeza. (kafka 指的是 docker 容器名称;它也可能被命名为 broker di sini, jadi semak semula perkhidmatan + nama hos anda).

Kunci: KAFKA_ADVERTISED_LISTENERS
Nilai: PLAINTEXT://kafka:9092,PLAINTEXT_HOST://localhost:29092

Sila ambil perhatian bahawa protokol di sini sepadan dengan nilai di sebelah kiri tetapan pemetaan protokol di atas

Apabila menjalankan bekas, tambahkan -p 29092:29092 进行主机端口映射,并通告 PLAINTEXT_HOST pendengar.

Jadi...(menggunakan tetapan di atas)

Jika masih tidak berfungsi, anda boleh menukar KAFKA_LISTENERS 设置为包含 9625b882931466931ca10eb1a60367b3://0.0.0.0:a3b0c87895079be75e30be94102cc20b di mana kedua-dua pilihan sepadan dengan tetapan iklan dan port yang dimajukan Docker

Pelanggan berada di mesin yang sama, bukan dalam bekas

Mengiklankan localhost dan port yang berkaitan akan membolehkan anda menyambung di luar bekas, seperti yang anda jangkakan.

Dalam erti kata lain, apabila menjalankan mana-mana klien Kafka (termasuk alat CLI yang mungkin anda pasang secara setempat) di luar rangkaian Docker, gunakan localhost:29092 作为引导服务器,使用 localhost:2181 sebagai Zookeeper (memerlukan penghantaran port Docker)

Pelanggan pada mesin lain

Jika cuba menyambung dari pelayan luaran, anda perlu mengiklankan nama hos/IP luaran hos (cth. 192.168.x.y) serta/bukan localhost .
Hanya mengiklankan localhost melalui pemajuan port tidak akan berfungsi kerana protokol Kafka masih akan terus mengiklankan pendengar yang dikonfigurasikan anda.

Persediaan ini memerlukan pemajuan port Docker dan pemajuan port penghala (dan perubahan firewall/kumpulan keselamatan) jika tidak pada rangkaian tempatan yang sama, contohnya, bekas anda berjalan di awan dan anda mahu berinteraksi dengannya daripada mesin tempatan anda .

Pelanggan (atau proksi lain) dalam bekas pada hos yang sama

Ini adalah konfigurasi yang paling tidak terdedah kepada ralat; anda boleh menggunakan nama perkhidmatan DNS secara langsung.

Apabila menjalankan aplikasi dalam rangkaian Docker , gunakan kafka:9092 (请参阅上面广告的 PLAINTEXT 侦听器配置)作为引导服务器,使用 zookeeper:2181 (lihat konfigurasi pendengar PLAINTEXT yang diiklankan di atas) sebagai pelayan bootstrap dan zookeeper:2181 sebagai Zookeeper , hanya seperti mana-mana komunikasi perkhidmatan Docker yang lain (tanpa sebarang penghantaran port diperlukan)

Jika anda menggunakan berasingan docker run 命令或 Compose 文件,则需要使用 compose networks 部分或 docker network --create 手动定义共享 network

Lihat contoh Karang fail untuk timbunan Confluence penuh atau untuk yang lebih ringkas untuk satu broker.

Jika menggunakan berbilang proksi maka mereka perlu menggunakan nama hos unik + pendengar iklan. Lihat contoh一个>

Soalan berkaitan

Sambung ke Kafka pada hos daripada Docker (ksqlDB)

Lampiran

Untuk sesiapa yang berminat dengan Kubernetes kerahan:

Atas ialah kandungan terperinci Sambung ke Kafka berjalan di Docker. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Artikel ini dikembalikan pada:stackoverflow.com. Jika ada pelanggaran, sila hubungi admin@php.cn Padam