簡體   English   中英

Sprint 啟動 kafka Consumer 無法連接到 kafka 容器

[英]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設置為本地主機時:

  • 您的應用程序在“Intellij”上運行,這意味着在主機環境中運行。 該主機創建 Kafka 的容器,因此來自 localhost:9092 的訪問將指向 Kafka 的容器。
  • 當您的應用在容器內運行時,localhost:9092 表示容器本身。 所以毫無意義。 (這個容器甚至沒有任何監聽 9092 端口的進程)

在容器環境中運行 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM