Java 如何在docker内部获得卡夫卡的解析网络?

Java 如何在docker内部获得卡夫卡的解析网络?,java,docker,apache-kafka,Java,Docker,Apache Kafka,我有一个spring应用程序,它应该连接到kafka。这是我的Docker文件为spring应用程序查找的内容: FROM maven:3-jdk-11 as builder # create app folder for sources RUN mkdir -p /build WORKDIR /build COPY pom.xml /build #Download all required dependencies into one layer RUN mvn -B dependency:re

我有一个spring应用程序,它应该连接到kafka。这是我的Docker文件为spring应用程序查找的内容:

FROM maven:3-jdk-11 as builder
# create app folder for sources
RUN mkdir -p /build
WORKDIR /build
COPY pom.xml /build
#Download all required dependencies into one layer
RUN mvn -B dependency:resolve dependency:resolve-plugins
#Copy source code
COPY src /build/src
# Build application
RUN mvn package

FROM openjdk:8-jdk-alpine
RUN addgroup -S spring && adduser -S spring -G spring
USER spring:spring
ARG JAR_FILE=target/*.jar
COPY ${JAR_FILE} app.jar
ENTRYPOINT ["java","-jar","/app.jar"]
卡夫卡/博士后/动物园管理员——其他一切都来自Docker图像。Think将在docker compose中运行应用程序,因此它看起来如下所示:

version: '3.1'
services:
    postgres:
        image: debezium/postgres
        environment:
          POSTGRES_PASSWORD: qwerty
          POSTGRES_USER: appuser
        volumes:
           - ./postgres:/data/postgres
        ports:
          - 6532:6532
    zookeeper:
        image: confluentinc/cp-zookeeper
        ports:
          - "2181:2181"
        environment:
          ZOOKEEPER_CLIENT_PORT: 2181
    kafka:
        image: confluentinc/cp-kafka
        depends_on:
          - zookeeper
          - postgres
        ports:
          - "9092:9092"
        environment:
          KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181
          KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://kafka:9092
          KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1
          KAFKA_LOG_CLEANER_DELETE_RETENTION_MS: 5000
          KAFKA_BROKER_ID: 1
          KAFKA_MIN_INSYNC_REPLICAS: 1
          KAFKA_ADVERTISED_HOST_NAME: kafka
    connector:
        image: debezium/connect:latest
        ports:
          - "8083:8083"
        environment:
          GROUP_ID: 1
          CONFIG_STORAGE_TOPIC: my_connect_configs
          OFFSET_STORAGE_TOPIC: my_connect_offsets
          BOOTSTRAP_SERVERS: kafka:9092
        depends_on:
          - zookeeper
          - postgres
          - kafka
    app-server:
    # Configuration for building the docker image for the backend service
        build:
          context: . # Use an image built from the specified dockerfile in the `polling-app-server` directory.
          dockerfile: Dockerfile
        ports:
          - "8080:8080" # Forward the exposed port 8080 on the container to port 8080 on the host machine
        restart: always
        depends_on: 
          - kafka 
          - zookeeper
          - postgres
          - connector
        environment:
          BOOTSTRAP_SERVERS: kafka:9092  
System.getenv("bootstrap.servers")
// or
System.getenv("BOOTSTRAP_SERVERS")
我传递了一个环境变量
BOOTSTRAP\u SERVERS
,其值为
kafka:9092
(因为
localhost:9092
在我的docker环境中不起作用)

在我的spring代码中,我得到如下值:

version: '3.1'
services:
    postgres:
        image: debezium/postgres
        environment:
          POSTGRES_PASSWORD: qwerty
          POSTGRES_USER: appuser
        volumes:
           - ./postgres:/data/postgres
        ports:
          - 6532:6532
    zookeeper:
        image: confluentinc/cp-zookeeper
        ports:
          - "2181:2181"
        environment:
          ZOOKEEPER_CLIENT_PORT: 2181
    kafka:
        image: confluentinc/cp-kafka
        depends_on:
          - zookeeper
          - postgres
        ports:
          - "9092:9092"
        environment:
          KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181
          KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://kafka:9092
          KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1
          KAFKA_LOG_CLEANER_DELETE_RETENTION_MS: 5000
          KAFKA_BROKER_ID: 1
          KAFKA_MIN_INSYNC_REPLICAS: 1
          KAFKA_ADVERTISED_HOST_NAME: kafka
    connector:
        image: debezium/connect:latest
        ports:
          - "8083:8083"
        environment:
          GROUP_ID: 1
          CONFIG_STORAGE_TOPIC: my_connect_configs
          OFFSET_STORAGE_TOPIC: my_connect_offsets
          BOOTSTRAP_SERVERS: kafka:9092
        depends_on:
          - zookeeper
          - postgres
          - kafka
    app-server:
    # Configuration for building the docker image for the backend service
        build:
          context: . # Use an image built from the specified dockerfile in the `polling-app-server` directory.
          dockerfile: Dockerfile
        ports:
          - "8080:8080" # Forward the exposed port 8080 on the container to port 8080 on the host machine
        restart: always
        depends_on: 
          - kafka 
          - zookeeper
          - postgres
          - connector
        environment:
          BOOTSTRAP_SERVERS: kafka:9092  
System.getenv("bootstrap.servers")
// or
System.getenv("BOOTSTRAP_SERVERS")
但是,当我运行
docker compose up
时,对于上述Java代码,我得到的值为
null
。不确定,为我的卡夫卡获取docker解析网络的最佳方法是什么

那么,如何修复它,以便java代码在docker环境中获取Kafka代理?

以下是一些建议,这些建议可能无法为您提供完整的解决方案(并且您的问题可能来自其他地方或其他系统问题),但也可能对您有所帮助:

一) docker compose文件的修正和改进

从中,您可以使用字典或列表定义环境参数。在您的情况下,您决定使用字典,但也许您可以尝试使用此处的列表(或我下面解释的
.env
文件)来实现:

1) 你应该在每个新定义的开头加一个“-”

2) 您应该使用等号(而不是列)

3) 最后但并非最不重要的一点:由于变量包含特殊字符(端口列),因此应使用引号转义所有定义:

    environment:
       - 'BOOTSTRAP_SERVERS=kafka:9092'
现在,如果您真的想使用字典表示法,您仍然需要转义列(“kafka:9092”),否则这可能会被(YAML解析器)解释为一个新的嵌套字典()

因此:

但最佳做法是使用
.env
文件,其内容非常简单:

BOOTSTRAP\u SERVERS=kafka:9092

然后从docker compose中删除您的
环境
定义并传递此选项:

env_file:
  - ./<name_of_your_env_file>.env
三) 根本不需要定义此环境变量

最后一件事(正如我在问题评论中所说):当您使用docker compose时,将使用此工具为您构建一个docker网络

通过调用您在yaml文件中提供的服务名称,可以访问每个容器

因此,在代码中,您只需要调用“kafka”服务

现在,如果您使用环境变量,当然,它为您注入不同的服务名称以进行测试提供了一些灵活性(假设明天您想要使用NATS或RabbitMQ,您可以通过更改环境变量来更改依赖项),但作为第一步,您可以尝试调用“kafka”直接服务并查看它是否连接:通过这种方式,您将消除这种可能性…

以下是一些建议,这些建议可能无法为您提供完整的解决方案(您的问题可能来自另一个地方或另一个系统问题),但也可能有助于您:

一) docker compose文件的修正和改进

从中,您可以使用字典或列表定义环境参数。在您的情况下,您决定使用字典,但也许您可以尝试使用此处的列表(或我下面解释的
.env
文件)来实现:

1) 你应该在每个新定义的开头加一个“-”

2) 您应该使用等号(而不是列)

3) 最后但并非最不重要的一点:由于变量包含特殊字符(端口列),因此应使用引号转义所有定义:

    environment:
       - 'BOOTSTRAP_SERVERS=kafka:9092'
现在,如果您真的想使用字典表示法,您仍然需要转义列(“kafka:9092”),否则这可能会被(YAML解析器)解释为一个新的嵌套字典()

因此:

但最佳做法是使用
.env
文件,其内容非常简单:

BOOTSTRAP\u SERVERS=kafka:9092

然后从docker compose中删除您的
环境
定义并传递此选项:

env_file:
  - ./<name_of_your_env_file>.env
三) 根本不需要定义此环境变量

最后一件事(正如我在问题评论中所说):当您使用docker compose时,将使用此工具为您构建一个docker网络

通过调用您在yaml文件中提供的服务名称,可以访问每个容器

因此,在代码中,您只需要调用“kafka”服务


现在,如果您使用环境变量,当然,它为您注入不同的服务名称以进行测试提供了一些灵活性(假设明天您想要使用NATS或RabbitMQ,您可以通过更改环境变量来更改依赖项),但作为第一步,您可以尝试调用“kafka”直接服务并查看它是否已连接:通过这种方式,您将消除这种可能性…

为什么不
System.getenv(“BOOTSTRAP\u SERVERS”)
,var的实际名称?我也尝试过。。但没有成功。@Ant的u是否将kafka指向etc/hosts文件中的localhost?你在那里做了什么?我们需要在
/etc/host
中更改吗?这是在码头工人内部运行的,对吗?你能澄清你的问题是什么吗。您是否在问如何编写Java代码来查找环境变量?或者您的Java代码无法连接到Kafka代理?或者什么?为什么不使用var的实际名称
System.getenv(“BOOTSTRAP\u SERVERS”)
?我也试过了。。但没有成功。@Ant的u是否将kafka指向etc/hosts文件中的localhost?你在那里做了什么?我们需要在
/etc/host
中更改吗?这是在码头工人里面运行的,对吗?你能澄清一下你的问题吗