Кафка + Java-приложение. в Докере на локальном компьютере

У меня есть приложение микросервиса Java Spring Boot, использующее Postgresql и Kafka в MacOS. Есть 2 модуля - киносервис и ивент-сервис. Filmservice получил производителя кафки, eventservice получил потребителя кафки. Когда я пытаюсь запустить его в контейнере Docker, модули приложения не могут подключиться к серверу Kafka.

Filmservice (продюсер) получил эту ошибку:

2024-09-05 14:12:10 filminator-filmservice  | 2024-09-05T11:12:10.978Z  INFO 1 --- [           main] o.a.k.c.c.internals.LegacyKafkaConsumer  : [Consumer clientId=consumer-my-group-id-1, groupId=my-group-id] Subscribed to topic(s): my-topic
2024-09-05 14:12:10 filminator-filmservice  | 2024-09-05T11:12:10.990Z  INFO 1 --- [           main] c.z.f.filmservice.FilminatorFilmService  : Started FilminatorFilmService in 1.974 seconds (process running for 2.223)
2024-09-05 14:12:11 filminator-filmservice  | 2024-09-05T11:12:11.102Z  INFO 1 --- [ntainer#0-0-C-1] org.apache.kafka.clients.NetworkClient   : [Consumer clientId=consumer-my-group-id-1, groupId=my-group-id] Node -1 disconnected.
2024-09-05 14:12:11 filminator-filmservice  | 2024-09-05T11:12:11.103Z  WARN 1 --- [ntainer#0-0-C-1] org.apache.kafka.clients.NetworkClient   : [Consumer clientId=consumer-my-group-id-1, groupId=my-group-id] Connection to node -1 (localhost/127.0.0.1:9092) could not be established. Node may not be available.
2024-09-05 14:12:11 filminator-filmservice  | 2024-09-05T11:12:11.103Z  WARN 1 --- [ntainer#0-0-C-1] org.apache.kafka.clients.NetworkClient   : [Consumer clientId=consumer-my-group-id-1, groupId=my-group-id] Bootstrap broker localhost:9092 (id: -1 rack: null) disconnected

eventservice(consumer) получил эту ошибку:

2024-09-05 14:14:58 filminator-eventservice  | 2024-09-05T11:14:58.843Z  WARN 1 --- [ntainer#1-0-C-1] org.apache.kafka.clients.NetworkClient   : [Consumer clientId=consumer-my-group-id-2, groupId=my-group-id] Connection to node -1 (localhost/127.0.0.1:9092) could not be established. Node may not be available.

Я пытаюсь остановить приложение в контейнере и запустить его из IDE - приложение успешно подключено к серверу контейнера Kafka.

docker-compose

services:

  zookeeper:
    image: 'bitnami/zookeeper:latest'
    ports:
      - '2182:2182'
    environment:
      - ALLOW_ANONYMOUS_LOGIN=yes

  kafka:
    image: 'bitnami/kafka:latest'
    ports:
      - '9092:9092'
    environment:
      - KAFKA_BROKER_ID=1
      - KAFKA_LISTENERS=PLAINTEXT://:9092
      - KAFKA_ADVERTISED_LISTENERS=PLAINTEXT://127.0.0.1:9092
      - KAFKA_ZOOKEEPER_CONNECT=zookeeper:2181
      - ALLOW_PLAINTEXT_LISTENER=yes
    depends_on:
      - zookeeper

  userservice:
    build: eventservice
    image: eventservice-image
    container_name: filminator-eventservice
    ports:
      - "8082:8082"
    depends_on:
      - kafka
      - filmservice
      - postgres_db
    environment:
      - SPRING_DATASOURCE_URL=jdbc:postgresql://postgres_db:5432/filminator

  filmservice:
      build: filmservice
      image: filmservice-image
      container_name: filminator-filmservice
      ports:
        - "8081:8081"
      depends_on:
        - kafka
        - postgres_db
      environment:
        - SPRING_DATASOURCE_URL=jdbc:postgresql://postgres_db:5432/filminator


  postgres_db:
      image: postgres:13.7-alpine
      volumes:
        - /var/lib/postgresql/data/
      container_name: db_postgres
      ports:
        - "6541:5432"
      environment:
        - POSTGRES_DB=filminator
        - POSTGRES_USER=postgres
        - POSTGRES_PASSWORD=iamroot

Докерфайл:

FROM openjdk:19
COPY target/*.jar app.jar
ENTRYPOINT ["java","-jar","/app.jar"]

application.properties

киносервис:

server.port=8081
spring.datasource.driver-class-name=org.postgresql.Driver
spring.sql.init.mode=always
spring.datasource.url=jdbc:postgresql://localhost:5432/filminator
spring.datasource.username=postgres
spring.datasource.password=iamroot

spring.kafka.bootstrap-servers=localhost:9092
spring.kafka.consumer.group-id=my-group-id

служба событий:

server.port=8082

другое приложение eventservice.свойства идентичны FilmService

Есть ли способ запустить мое приложение и сервер Kafka в одном докер-контейнере?

localhost — это Docker-контейнер. Kafka работает в другом контейнере. Вам необходимо указать имена этих контейнеров.
knittl 05.09.2024 13:42

...вероятно, установив SPRING_KAFKA_BOOTSTRAPSERVERS почти так же, как вы установили SPRING_DATASOURCE_URL.

David Maze 05.09.2024 13:44
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
2
52
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Вам нужно добавить хост в файл docker-compose, см. этот пример

  kafka:
    image: 'bitnami/kafka:latest'
    hostname: kafka
    ports:
      - '9092:9092'
    environment:
      - KAFKA_BROKER_ID=1
      - KAFKA_LISTENERS=PLAINTEXT://:9092
      - KAFKA_ADVERTISED_LISTENERS=PLAINTEXT://127.0.0.1:9092
      - KAFKA_ZOOKEEPER_CONNECT=zookeeper:2181
      - ALLOW_PLAINTEXT_LISTENER=yes
    depends_on:
      - zookeeper

Затем вы можете подключиться внутри сети докера следующим образом.

spring.kafka.bootstrap-servers=kafka:9092

Я думаю, что имя хоста по умолчанию соответствует имени контейнера.

Я добавляю имя хоста: kafka в службу kafka и имя хоста: Zookeeper в службу Zookeeper. В моем application.properties я изменил Spring.kafka.bootstrap-servers=localhost:9092 на Spring.kafka.bootstrap-servers=kafka:9092. В моих классах конфигурации потребителей/производителей я меняю configProps.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, "kafka:9092"); с «localhost:9092» на «kafka:9092»);

Zholtikov Alexander 06.09.2024 09:29

При запуске в докере появляется предупреждение: kafka: WARN [Controller id=1, targetBrokerId=1] Не удалось установить соединение с узлом 1 (/127.0.0.1:9092). Узел может быть недоступен. (org.apache.kafka.clients.NetworkClient) 06.09.2024 10:07:56 Кафка | [2024-09-06 07:07:56,652] ПРЕДУПРЕЖДЕНИЕ [RequestSendThread ControllerId=1] Подключение контроллера 1 к брокеру 127.0.0.1:9092 (идентификатор: 1 стойка: ноль) не удалось (kafka.controller.RequestSendThread) 2024-09- 06 10:07:56 Кафка | java.io.IOException: подключение к 127.0.0.1:9092 (идентификатор: 1 стойка: ноль) не удалось. но приложение, запущенное в IDE, может его использовать

Zholtikov Alexander 06.09.2024 09:33

фильмсервис (продюсер) из того же контейнера - запускается без ошибок, но при попытке отправить сообщение Кафки - получена ИНФОРМАЦИЯ [Producer clientId=producer-1] Узел 1 отключен WARN [Producer clientId=producer-1] Соединение с узлом 1 (/127.0) .0.1:9092) не удалось установить. Узел может быть недоступен. Пользовательская служба (потребитель) получила ошибки при запуске: INFO [Consumer clientId=consumer-my-group-id-2, groupId=my-group-id] Узел 1 отключен. ПРЕДУПРЕЖДЕНИЕ [Consumer clientId=consumer-my-group-id-2, groupId=my-group-id] Не удалось установить соединение с узлом 1 (/127.0.0.1:9092). Узел может быть недоступен.

Zholtikov Alexander 06.09.2024 09:34

Я решил проблему.

В файле docker-compose я меняю настройки сервисов Zookeeper и Kafka:

 zookeeper:
  image: confluentinc/cp-zookeeper:latest
  environment:
    ZOOKEEPER_CLIENT_PORT: 2181
    ZOOKEEPER_TICK_TIME: 2000
  ports:
    - 22181:2181

kafka:
  image: confluentinc/cp-kafka:latest
  depends_on:
    - zookeeper
  ports:
    - 29092:29092
  environment:
    KAFKA_BROKER_ID: 1
    KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181
    KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://kafka:9092,PLAINTEXT_HOST://localhost:29092
    KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: PLAINTEXT:PLAINTEXT,PLAINTEXT_HOST:PLAINTEXT
    KAFKA_INTER_BROKER_LISTENER_NAME: PLAINTEXT
    KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1

в application.properties измените загрузочные серверы с localhost на kafka: spring.kafka.bootstrap-servers=kafka:9092

В моих классах конфигурации потребителей/производителей изменяются с localhost на kafka :

configProps.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, "kafka:9092");

Теперь это работает.

Другие вопросы по теме