java - 如何在docker内部获取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: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"]
kafka/Postgres/zookeeper 其他一切都来自 Docker 镜像。所以想到会在 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
我传递了一个BOOTSTRAP_SERVERS
值为 as的环境变量kafka:9092
(因为localhost:9092
在我的 docker 环境中不起作用)。
在我的 spring 代码中,我得到如下值:
System.getenv("bootstrap.servers")
// or
System.getenv("BOOTSTRAP_SERVERS")
但是,当我运行时docker-compose up
,我得到null
了上述 Java 代码的值。不确定,为我的 kafka 获取 docker 解析网络的最佳方法是什么。
那么如何修复它,以便 java 代码在 docker 环境中获取 Kafka 代理呢?
解决方案
以下是一些可能无法为您提供完整解决方案的建议(您的问题可能来自其他地方或其他系统问题),但也可能对您有所帮助:
I)未成年人修复和改进 docker-compose 文件
从文档中,您可以使用字典 或列表来定义环境参数。在您的情况下,您决定使用字典,但也许您可以尝试在此处使用列表(或.env
我在下面解释的文件):
1)您应该在每个新定义的开头添加一个“-”
2)你应该使用等号(不是列)
3)最后但同样重要的是:由于您的变量包含特殊字符(端口列),您应该使用引号转义所有定义:
environment:
- 'BOOTSTRAP_SERVERS=kafka:9092'
现在,如果您真的想使用字典表示法,您仍然需要转义列 ("kafka:9092") 否则这可能会(由 YAML 解析器)解释为新的嵌套字典(请参见此处的主机连接字符串示例)
所以 :
environment:
BOOTSTRAP_SERVERS: 'kafka:9092'
但是最好的做法是使用一个.env
文件,它的内容很简单:
BOOTSTRAP_SERVERS=kafka:9092
environment
然后从 docker-compose中删除您的定义并传递此选项:
env_file:
- ./<name_of_your_env_file>.env
现在请记住,如果您决定同时使用.env
文件environment
和shell
变量(例如)(参见此处) ,则环境定义中存在优先级。
- 编写文件
- 外壳环境变量
- 环境文件
- Dockerfile
- 变量未定义
二)Tomcat默认嵌入式服务器
我发现的另一件事:
因为您使用的是 Spring:它的默认嵌入式服务器是 Tomcat(除非您在依赖项中更改了它)。从 AWS文档(即使您不使用它,它也可以引导您找到解决方案):
Java SE 平台设置您使用 System.getenv 检索的环境变量,而Tomcat 平台设置您使用 System.getProperty 检索的 Java 系统属性。
所以也许尝试:
System.getProperty("BOOTSTRAP_SERVERS")
III)根本不需要定义这个环境变量:
最后一件事(正如我在问题评论中所说):当您使用 docker-compose 时,此工具会为您构建一个docker 网络。
可以通过调用您在 yaml 文件中提供的服务名称来访问每个容器。
所以在你的代码中,你只需要调用“kafka”服务。
现在,如果您使用环境变量,当然,它为您注入不同的服务名称进行测试提供了一些灵活性(假设明天您想使用 NATS 或 RabbitMQ,您将能够通过更改环境变量来更改依赖关系)但作为第一步,也许您可以尝试直接调用“kafka”服务并查看它是否已连接:通过这种方式,您将消除这种可能性......
推荐阅读
- python - Django 表单小部件不显示错误
- sql - 取消的更新语句正在阻止 SQL Server 中表的删除语句
- angular - 角度检测对象属性更改
- python-3.x - 请更正我的代码并告诉我我做错了什么?
- apache-kafka - 为什么 ksql 不支持右外连接?
- javascript - Canvas 2D 或 p5.js 中是否有某种 VBO/VAO?
- python - 如何选择网站的各种元素
- python-3.x - 在 Ubuntu 上部署 python REST 服务
- python - create() 接受 1 个位置参数但给出了 2 个?姜戈
- angular - 所有测试通过后 Jasmine 抛出错误