简体   繁体   English

Docker (Compose) 客户端过早连接到 Kafka

[英]Docker (Compose) client connects to Kafka too early

I am trying to run Kafka with Docker and Docker Compose.我正在尝试使用 Docker 和 Docker Compose 运行 Kafka。 This is the docker-compose.yml :这是docker-compose.yml

version: "2"

services:
  zookeeper:
    image: "wurstmeister/zookeeper"
    ports:
      - "2181:2181"

  kafka:
    build:
      context: "./services/kafka"
      dockerfile: "Dockerfile"
    ports:
      - "9092:9092"
    environment:
      KAFKA_ADVERTISED_HOST_NAME: "0.0.0.0"
      KAFKA_CREATE_TOPICS: "test:1:1"
      KAFKA_ZOOKEEPER_CONNECT: "zookeeper:2181"
    volumes:
      - "/var/run/docker.sock:/var/run/docker.sock"

  users:
    build:
      context: "./services/users"
      dockerfile: "Dockerfile"
    ports:
      - "4001:4001"
    environment:
      NODE_ENV: "develop"
      ZOOKEEPER_HOST: "zookeeper"
      ZOOKEEPER_PORT: "2181"
    volumes:
      - "./services/users:/service"

The users service only tries to connect (using kafka-node in Node.js) and listens on a topic and publishes one message to it every time it is ran.用户服务仅尝试连接(使用 Node.js 中的 kafka-node)并监听一个主题并在每次运行时向其发布一条消息。

The problem is that I keep getting Connection Refused errors.问题是我不断收到 Connection Refused 错误。 I am using Dockerize to wait for the kafka port to be available in the Dockerfile with the line CMD dockerize -wait tcp://kafka:9092 node /service/index.js .我正在使用 Dockerize 等待 Dockerfile 中的 kafka 端口可用, Dockerfile CMD dockerize -wait tcp://kafka:9092 node /service/index.js

It waits for the port to be available before starting the users container and this system works, but it is not at the right time.它在启动用户容器之前等待端口可用,并且该系统可以正常工作,但时间不对。 It seems that Kafka is opening the 9092 port before it has elected a leader.看起来 Kafka 在选出领导者之前就打开了 9092 端口。

When I run Kafka first and let it start completely and then run my app, it runs smoothly.当我先运行 Kafka 并让它完全启动然后运行我的应用程序时,它运行得很顺利。

How do I wait for the correct moment before starting my service?如何在开始服务之前等待正确的时间?

Try the docker-compose version 2.1 or 3, as it includes an healthcheck directive. 尝试使用docker-compose版本2.1或3,因为它包含一个healthcheck指令。
See " Docker Compose wait for container X before starting Y " as an example. 有关示例,请参阅“ Docker Compose在启动Y之前等待容器X ”。

You can: 您可以:

depends_on:
  kafka:
    condition: service_healthy

And in kafka add: 并在卡夫卡添加:

healthcheck:
    test: ["CMD", ...]
    interval: 30s
    timeout: 10s
    retries: 5

with a curl command for instance which would test if kafka has elected a leader. 例如,使用curl命令测试kafka是否选出了领导者。

A full example;一个完整的例子; this is what I use in docker compose.这就是我在 docker 撰写中使用的内容。

tldr; tldr; use a kafka healthcheck使用卡夫卡健康检查
["CMD", "kafka-topics.sh", "--list", "--zookeeper", "zookeeper:2181"]

  • integration test app depends on kafka集成测试应用依赖kafka
  • app depends on kafka应用依赖kafka
  • kafka depends on zookeeper kafka 依赖于 zookeeper

Since the integration test and the app are starting at the same time, I think this helps with total execution time.由于集成测试和应用程序同时启动,我认为这有助于缩短总执行时间。
Also, both are starting after kafka's healthcheck is passing.此外,两者都是在卡夫卡的健康检查通过后开始的。

version: '2.1'

services:

  my-integration-tests:
    image: golang:1.16
    volumes:
      - myapp:/app
    command: go test -tags=integration -mod=vendor -cover -v --ginkgo.v --ginkgo.progress --ginkgo.failFast
    depends_on:
      kafka:
        condition: service_healthy

  my-app:
    image: local/my-app
    build:
      context: .
    depends_on:
      kafka:
        condition: service_healthy

  zookeeper:
    image: wurstmeister/zookeeper:3.4.6
    expose:
      - "2181"
    tmpfs:
      - /opt/zookeeper-3.4.6/data

  kafka:
    image: wurstmeister/kafka:latest
    depends_on:
      - zookeeper
    expose:
      - 9092
    tmpfs:
      - /kafka
    environment:
      KAFKA_ADVERTISED_LISTENERS: INSIDE://localhost:9094,OUTSIDE://kafka:9092
      KAFKA_LISTENERS: INSIDE://:9094,OUTSIDE://:9092
      KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: INSIDE:PLAINTEXT,OUTSIDE:PLAINTEXT
      KAFKA_INTER_BROKER_LISTENER_NAME: INSIDE
      KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181
      LOG4J_LOGGER_KAFKA_AUTHORIZER_LOGGER: DEBUG, authorizerAppender
    healthcheck:
      test: ["CMD", "kafka-topics.sh", "--list", "--zookeeper", "zookeeper:2181"]
      interval: 5s
      timeout: 10s
      retries: 5

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM