Загрузочный контейнер Spring не может найти брокера kafka в другом контейнере - PullRequest
0 голосов
/ 08 марта 2020

У меня есть простое приложение springboot, работающее в контейнере docker со следующей конфигурацией.

@Configuration
public class ProducerConfiguration {

    private static final String KAFKA_BROKER = "kafka:9092";

    @Bean
    public ProducerFactory<String, String> producerFactory() {
        return new DefaultKafkaProducerFactory<>(producerConfigurations());
    }

    @Bean
    public Map<String, Object> producerConfigurations() {
        Map<String, Object> configurations = new HashMap<>();

        configurations.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, KAFKA_BROKER);
        configurations.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class);
        configurations.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, StringSerializer.class);

        return configurations;
    }

    @Bean
    public KafkaTemplate<String, String> kafkaTemplate() {
        return new KafkaTemplate<>(producerFactory());
    }

}

Класс контроллера

@RestController
public class KafkaController {

    private static final Logger LOGGER= LoggerFactory.getLogger(KafkaController.class);

    private KafkaTemplate<String, String> template;

    public KafkaController(KafkaTemplate<String, String> template) {
        this.template = template;
    }

    @GetMapping("/kafka/produce")
    public void produce(@RequestParam String message) {
        template.send("test_topic", message);


    }
}

В том же проекте ниже docker -compose.yml для kafka

version: '2.1'

services:
  app:
    restart: always
    build:
      context: ./
      dockerfile: Dockerfile
    image: app
    container_name: app

    ports:
      - 8080
    depends_on:
      - kafka
      - zookeeper
    networks:
      - network1

  kafka:
    image: wurstmeister/kafka
    container_name: 'kafka'
    environment:
      JVM_OPTS: -Xmx1g -Xms1g -XX:MaxPermSize=1024m
      KAFKA_ADVERTISED_HOST_NAME: kafka
      KAFKA_ADVERTISED_PORT: 9092
      KAFKA_CREATE_TOPICS: test_topic:1:1
      KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181
      KAFKA_INTER_BROKER_LISTENER_NAME: INSIDE
      KAFKA_LISTENERS: INSIDE://kafka:9093,OUTSIDE://0.0.0.0:9092
      KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: INSIDE:PLAINTEXT,OUTSIDE:PLAINTEXT
      KAFKA_ADVERTISED_LISTENERS: INSIDE://kafka:9093,OUTSIDE://localhost:9092

    depends_on:
      - zookeeper
    ports:
      - 9092:9092
      - 9093:9093
    networks:
      - network1


  zookeeper:
    container_name: 'zookeeper'
    image: wurstmeister/zookeeper

    networks:
      - network1

networks:
  network1:

Проблема: Когда я запускаю приложение springboot локально и пытаюсь отправить сообщение в topi c, оно работает нормально. Но когда я докеризую приложение springboot, используя docker build -t my/app, затем docker run --publish=8080:8080 my/app, а затем попробуйте отправить сообщение на topi c. Я получаю следующую ошибку

[Producer clientId=producer-1] Connection to node -1 (kafka/127.0.0.1:9092) could not be established. Broker may not be available.

Я пробовал различные предложения в отношении KAFKA_ADVERTISED_HOST_NAME, но все еще его не работает. Цените любую помощь по этому .

РЕДАКТИРОВАТЬ: мой dockerfile

FROM maven:3.5.2-jdk-8-alpine AS MAVEN_BUILD
COPY pom.xml /build/
COPY src /build/src/
WORKDIR /build/
RUN mvn package
FROM openjdk:8-jre-alpine
WORKDIR /app
COPY --from=MAVEN_BUILD /build/target/app-0.0.1-SNAPSHOT.jar /app/
ENTRYPOINT ["java", "-jar", "app-0.0.1-SNAPSHOT.jar"]

1 Ответ

1 голос
/ 08 марта 2020

Согласно комментарию, есть несколько вещей для запуска вашей весенней загрузки в той же сети, что и Kafka.

Узнайте, в какой сети находится Kafka,

docker inspect --format='{{json .NetworkSettings.Networks}}' <kafka_container_id>

response: {"<this_is_network_name>": ...}

Чтобы получить kafka_container_id a docker ps можно использовать.

Когда вы знаете сетевое имя, вы можете выполнить команду запуска, как в настоящее время, с помощью:

docker run --network <network_name> --publish=8080:8080  my/app

Я заметил, что вы обновили свой составной файл, сеть должна выглядеть примерно так:

networks:
  default:
    external:
      name: my-pre-existing-network

Но назначать их существующей сети не нужно, так как все они содержатся в одной композиции, поэтому по умолчанию им всем будет назначена одна и та же сеть, что-то вроде:


version: '2.1'

services:
  app:
    restart: always
    build:
      context: ./
    container_name: app

    ports:
      - 8080:8080
    depends_on:
      - kafka
      - zookeeper

  kafka:
    image: wurstmeister/kafka
    container_name: 'kafka'
    environment:
      JVM_OPTS: -Xmx1g -Xms1g -XX:MaxPermSize=1024m
      KAFKA_ADVERTISED_HOST_NAME: kafka
      KAFKA_ADVERTISED_PORT: 9092
      KAFKA_CREATE_TOPICS: test_topic:1:1
      KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181
      KAFKA_INTER_BROKER_LISTENER_NAME: INSIDE
      KAFKA_LISTENERS: INSIDE://kafka:9093,OUTSIDE://0.0.0.0:9092
      KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: INSIDE:PLAINTEXT,OUTSIDE:PLAINTEXT
      KAFKA_ADVERTISED_LISTENERS: INSIDE://kafka:9093,OUTSIDE://localhost:9092

    depends_on:
      - zookeeper
    ports:
      - 9092:9092
      - 9093:9093

  zookeeper:
    container_name: 'zookeeper'
    image: wurstmeister/zookeeper

Dockerfile также должен предоставлять 8080 (при условии, что вы хотите запустить приложение весенней загрузки)

...