[英]Sprint boot kafka Consumer can not connect to the kafka container
我正在嘗試部署 2 個 Spring 引導應用程序(kafka 生產者和消費者)。 當我將 Producer 部署到 docker 時一切正常,但是當我部署我的 Consumer 時不起作用,因為沒有與 kafka 容器的連接。
日志告訴我這個錯誤
2019-11-17 05:32:22.644 WARN 1 --- [main] o.a.k.c.NetworkClient: [Consumer clientId=consumer-1, groupId=exampleGroup] Connection to node -1 could not be established. Broker may not be available.
我的 docker-compose.yml 是
version: '3'
services:
zookeeper:
image: wurstmeister/zookeeper
container_name: zookeeper
restart: always
ports:
- 2181:2181
kafka:
image: wurstmeister/kafka
container_name: kafka
restart: always
ports:
- 9092:9092
depends_on:
- zookeeper
links:
- zookeeper:zookeeper
environment:
KAFKA_ADVERTISED_HOST_NAME: localhost
KAFKA_ADVERTISED_PORT: 9092
KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181
KAFKA_CREATE_TOPICS: "topic1:1:1"
在我的 KafkaConfig class 上:
@EnableKafka
@Configuration
public class KafkaConfig {
@Bean
public ConsumerFactory<String, String> consumerFactory(){
Map<String, Object> config = new HashMap<>();
config.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, KafkaConstants.KAFKA_BROKERS);
config.put(ConsumerConfig.GROUP_ID_CONFIG, "exampleGroup");
config.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class);
config.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class);
// config.put(ConsumerConfig.ENABLE_AUTO_COMMIT_CONFIG, KafkaConstants.ENABLE_AUTO_COMMIT_CONFIG);
config.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, KafkaConstants.OFFSET_RESET_EARLIER);
// config.put(ConsumerConfig.SESSION_TIMEOUT_MS_CONFIG, KafkaConstants.SESSION_TIMEOUT_MS);
return new DefaultKafkaConsumerFactory<>(config);
}
和常數 class
public class KafkaConstants {
public static String KAFKA_BROKERS = "localhost:9092";
public static Integer MESSAGE_COUNT=1000;
public static String TOPIC_NAME="demo";
public static String GROUP_ID_CONFIG="exampleGroup";
public static Integer MAX_NO_MESSAGE_FOUND_COUNT=100;
public static String OFFSET_RESET_LATEST="latest";
public static String OFFSET_RESET_EARLIER="earliest";
public static Integer MAX_POLL_RECORDS=1;
public static Integer SESSION_TIMEOUT_MS = 180000;
public static Integer REQUEST_TIMEOUT_MS_CONFIG = 181000;
public static String ENABLE_AUTO_COMMIT_CONFIG = "false";
public static Integer AUTO_COMMIT_INTERVAL_MS_CONFIG = 8000;
}
當我在我的計算機上安裝 zookepper 和 kafka 並使用 intellij 運行這 2 個 spring 啟動應用程序時工作正常。 問題是當我部署到本地 docker 時。
你能幫我么?
更新
更新我的 docker-compose:
version: '3'
services:
zookeeper:
image: wurstmeister/zookeeper
container_name: zookeeper
restart: always
ports:
- 2181:2181
kafka:
image: wurstmeister/kafka
container_name: kafka
restart: always
ports:
- 9092:9092
depends_on:
- zookeeper
links:
- zookeeper:zookeeper
environment:
KAFKA_ADVERTISED_HOST_NAME: kafka
KAFKA_ADVERTISED_PORT: 9092
KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181
KAFKA_CREATE_TOPICS: "ACC_GROUP_CREATE:1:1"
consumer:
image: micro1
container_name: micro1
depends_on:
- kafka
restart: always
ports:
- 8088:8088
depends_on:
- kafka
links:
- kafka:kafka
producer:
image: micro2
container_name: micro2
depends_on:
- kafka
restart: always
ports:
- 8087:8087
depends_on:
- kafka
links:
- kafka:kafka
工作正常! 基於@hqt 的響應,但我不知道為什么需要添加這些消費者/生產者行
由於KAFKA_ADVERTISED_HOST_NAME
屬性的問題。 這是解釋為什么 Kafka 需要廣告地址的文檔。
關鍵是當你運行一個客戶端時,你傳遞給它的代理就是它要去的地方 go 並從中獲取關於集群中代理的元數據。 它將連接到以讀取/寫入數據的實際主機和 IP 是基於代理在初始連接中傳回的數據- 即使它只是一個節點並且返回的代理與連接到的代理相同。
當您將KAFKA_ADVERTISED_HOST_NAME
設置為本地主機時:
在容器環境中運行 web 應用程序時,將KAFKA_ADVERTISED_HOST_NAME
屬性更新為kafka
將起作用。 請注意,您的 web 應用程序和 kafka 容器都必須在 docker 的網絡上。
這是建議的 docker-compose,用於使用 Wurstmeister 的圖像運行 Kafka 集群。
version: "2"
services:
zookeeper:
image: wurstmeister/zookeeper
container_name: zookeeper
ports:
- 2181:2181
kafka:
image: wurstmeister/kafka
container_name: kafka
ports:
- 9092:9092
depends_on:
- zookeeper
environment:
KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181
KAFKA_ADVERTISED_HOST_NAME: kafka
KAFKA_ADVERTISED_PORT: 9092
KAFKA_CREATE_TOPICS: "topic1:1:1"
web_app:
# your definition of the web_app goes here
然后你可以連接到容器環境內地址kafka:9092
上的 Kafka 代理。
這是一個常見問題,您需要閱讀和理解的權威文檔是https://www.confluent.io/blog/kafka-listeners-explained
我正在復制它的 tl;dr: 以供參考:
您需要將 Advertisementd.listeners (或 >KAFKA_ADVERTISED_LISTENERS 如果您使用 Docker >images)設置為外部地址(主機/IP),以便客戶端 > 可以正確連接到它。 否則,他們會嘗試連接 > 到內部主機地址——如果無法訪問,那么就會出現問題。”
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.