Spring Boot 应用程序无法在 Docker 中将事件发布到 Kafka

Posted

技术标签:

【中文标题】Spring Boot 应用程序无法在 Docker 中将事件发布到 Kafka【英文标题】:Spring Boot app is not able to publish events to Kafka in Docker 【发布时间】:2022-01-05 05:30:55 【问题描述】:

各位程序员大家好!

我正在学习 Docker 和 Kafka,如果有任何帮助,我将不胜感激。问题是应用程序能够连接到 Kafka,但不能发布任何事件。错误:

org.apache.kafka.common.errors.TimeoutException: Expiring 2 record(s) for wages-local-0:120001 ms has passed since batch creation

当一个 Docker 容器中的 Spring Boot 应用程序尝试发布到另一个容器中的 Kafka 时,会出现此问题:

version: '3'

services:
  zookeeper:
    image: wurstmeister/zookeeper
    container_name: zookeeper
    ports:
      - "2181:2181"
  kafka:
    image: wurstmeister/kafka
    container_name: kafka
    hostname: kafka
    ports:
      - "9092:9092"
    environment:
      KAFKA_BROKER_ID: 1
      KAFKA_ADVERTISED_PORT: 9092
      KAFKA_ADVERTISED_HOST_NAME: kafka
      KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181
      KAFKA_LISTENERS: INTERNAL://kafka:9092
      KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://kafka:9092
      KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: INTERNAL:PLAINTEXT
      KAFKA_INTER_BROKER_LISTENER_NAME: INTERNAL
    depends_on:
      - zookeeper
  publisher_app:
    build:
      context: ./kafka-publisher
    ports:
      - 8080:8080
    depends_on:
      - "kafka"
    environment:
      kafka.wages-topic.bootstrap-address: kafka:9092
    links:
      - kafka:kafka

这里是源代码链接:https://github.com/aleksei17/springboot-rest-kafka-mysql/blob/master/docker-compose.yml

【问题讨论】:

你能从你的主机ping到那个容器吗?这似乎是 docker 容器中的网络问题。按照以下链接获取解决方案:- ***.com/questions/24319662/… kafka.wages-topic.bootstrap-address 看起来不像环境变量 这是一个来自 application.yml 的变量,在这里使用它:github.com/aleksei17/springboot-rest-kafka-mysql/blob/master/… 【参考方案1】:

好吧,看来我需要在使用后删除容器。当我这样做时,在启动 Kafka 容器时出现错误,例如:unknown listener PLAINTEXT。所以我将 PLAINTEXT 更改为 INTERNAL,它起作用了!这是 Kafka 的 docker-compose 的最终版本:

  kafka:
    image: wurstmeister/kafka
    container_name: kafka
    hostname: kafka
    ports:
      - "9092:9092"
    environment:
      KAFKA_BROKER_ID: 1
      KAFKA_ADVERTISED_PORT: 9092
      KAFKA_ADVERTISED_HOST_NAME: kafka
      KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181
      KAFKA_LISTENERS: INTERNAL://kafka:9092
      KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://kafka:9092
      KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: INTERNAL:PLAINTEXT
      KAFKA_INTER_BROKER_LISTENER_NAME: INTERNAL
    depends_on:
      - zookeeper

如果它既适用于 Dockerized 应用程序,也适用于在 Docker 之外的同一主机上运行的应用程序,那就太好了,但这是另一回事。玩过这个教程,但到目前为止没有成功:https://www.baeldung.com/kafka-docker-connection

【讨论】:

你只有一个监听器和一个broker,PLAINTEXT是内置的,所以你不需要映射或者inter-broker监听器【参考方案2】:

您的配置被硬编码为使用localhost:9092

您想像这样 externalize the config (删除您的 kafka.wages-topic 部分,因为引导服务器不是特定于主题的设置)

spring:
  kafka:
    bootstrap-servers: $BOOTSTRAP_SERVERS

然后在 Compose 中,

environment:
  BOOTSTRAP_SERVERS: kafka:9092

要配置主题,请参阅https://docs.spring.io/spring-kafka/reference/html/#configuring-topics

【讨论】:

感谢您的回答! localhost:9092 似乎没有问题,因为这在 docker-compose 中被 kafka.wages-topic.bootstrap-address 覆盖。我宁愿离开 application.yml 以便从 IntelliJ 运行更容易 您可以将环境变量添加到 IntelliJ Run Configurations 以使其在两种情况下都能正常工作

以上是关于Spring Boot 应用程序无法在 Docker 中将事件发布到 Kafka的主要内容,如果未能解决你的问题,请参考以下文章

使用docker构建第一个spring boot项目

Docker环境下Spring Boot应用内存飙升分析与解决

无法在 Azure 中部署 Spring Boot 应用程序

无法在 IntelliJ Idea 中启动 spring-boot 应用程序

Spring Boot 应用程序使用 spring-boot-starter-actuator 给出“无法启动 tomcat”异常

为啥 spring-boot 应用程序无法在 AWS 中运行,但在本地运行良好?