Докер Кафка с питоном - PullRequest
       6

Докер Кафка с питоном

0 голосов
/ 21 сентября 2018

Я использую Dockerized Kafka и написал одну потребительскую программу Kafka.Он отлично работает, когда я запускаю Kafka в докере и приложении на моей локальной машине.Но когда я настроил локальное приложение в Docker, я столкнулся с проблемами.Возможно, проблема связана с темой, которая не была создана до момента запуска приложения.

docker-compose.yml

version: '3'
services:
  zookeeper:
    image: wurstmeister/zookeeper
    ports:
      - "2181:2181"
  kafka:
    image: wurstmeister/kafka
    ports:
      - "9092:9092"
    environment:
      KAFKA_ADVERTISED_HOST_NAME: localhost
      KAFKA_CREATE_TOPICS: "test:1:1"
      KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
  parse-engine:
    build: .
    depends_on:
      - "kafka"
    command: python parse-engine.py
    ports:
     - "5000:5000"

parse-engine.py

from kafka import KafkaConsumer
import json

try:
    print('Welcome to parse engine')
    consumer = KafkaConsumer('test', bootstrap_servers='localhost:9092')
    for message in consumer:
        print(message)
except Exception as e:
    print(e)
    # Logs the error appropriately. 
    pass

Ошибкаlog

kafka_1         | [2018-09-21 06:27:17,400] INFO [SocketServer brokerId=1001] Started processors for 1 acceptors (kafka.network.SocketServer)
kafka_1         | [2018-09-21 06:27:17,404] INFO Kafka version : 2.0.0 (org.apache.kafka.common.utils.AppInfoParser)
kafka_1         | [2018-09-21 06:27:17,404] INFO Kafka commitId : 3402a8361b734732 (org.apache.kafka.common.utils.AppInfoParser)
kafka_1         | [2018-09-21 06:27:17,431] INFO [KafkaServer id=1001] started (kafka.server.KafkaServer)
**parse-engine_1  | Welcome to parse engine
parse-engine_1  | NoBrokersAvailable 
parseengine_parse-engine_1 exited with code 0**
kafka_1         | creating topics: test:1:1

Как я уже добавил depen_on свойство в docker-compose, но перед тем, как запустить приложение для подключения к теме, произошла ошибка.

Я прочитал, что могу добавить скрипт в файл docker-compose, но я ищу какой-нибудь простой способ.

Спасибо за помощь

Ответы [ 2 ]

0 голосов
/ 21 сентября 2018

Эта строка

KAFKA_ADVERTISED_HOST_NAME: localhost

Говорит, что брокер рекламирует себя как доступный только на localhost, что означает, что все клиенты Kafka будут получать только самому себе, а не фактический список адресов реальных брокеров.

В нем должно быть написано KAFKA_ADVERTISED_HOST_NAME: kafka, где kafka - это имя Docker Compose Service.


Затем эта строка

consumer = KafkaConsumer('test', bootstrap_servers='localhost:9092')

Вы указываете контейнер Python на себя , а не контейнер kafka.

Стоит сказать kafka:9092 вместо

0 голосов
/ 21 сентября 2018

Ваша проблема в сети.В вашей конфигурации Kafka вы устанавливаете

KAFKA_ADVERTISED_HOST_NAME: localhost

, но это означает, что любой клиент (включая ваше приложение python) будет подключаться к брокеру, а затем брокеру будет сказано использовать localhost для любых соединений,Поскольку localhost с вашего клиентского компьютера (например, вашего контейнера python) находится не там, где находится брокер, запросы не будут выполнены.

Подробнее о слушателях Kafka вы можете прочитать здесь: https://rmoff.net/2018/08/02/kafka-listeners-explained/

Итак, чтобы исправить проблему, вы можете сделать одно из двух:

  1. Просто измените ваш состав, чтобы использовать внутреннее имя хоста для Kafka (KAFKA_ADVERTISED_HOST_NAME: kafka).Это означает, что любые клиенты в пределах в сети докера смогут нормально получить к ней доступ, но никакие внешние клиенты не смогут (например, с вашего хоста):

    version: '3'
    services:
    zookeeper:
        image: wurstmeister/zookeeper
        ports:
        - "2181:2181"
    kafka:
        image: wurstmeister/kafka
        ports:
        - "9092:9092"
        environment:
        KAFKA_ADVERTISED_HOST_NAME: kafka
        KAFKA_CREATE_TOPICS: "test:1:1"
        KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181
        volumes:
        - /var/run/docker.sock:/var/run/docker.sock
    parse-engine:
        build: .
        depends_on:
        - "kafka"
        command: python parse-engine.py
        ports:
        - "5000:5000"
    

    Ваши клиенты будут затем обращаться к брокеру по адресу kafka: 9092, поэтому ваше приложение на python изменится на

    consumer = KafkaConsumer('test', bootstrap_servers='kafka:9092')
    
  2. Добавить нового слушателя Kafka.Это позволяет получить к нему доступ как внутри, так и снаружи к докерной сети.Порт 29092 предназначен для доступа внешний к сети докеров (например, с вашего хоста) и 9092 для доступа внутренний .

    Вам все равно нужно изменить свою программу на Python, чтобы получить доступ к Kafka по правильному адресу.В этом случае, поскольку он внутренний для сети Docker, вы должны использовать:

    consumer = KafkaConsumer('test', bootstrap_servers='kafka:9092')
    

    Так как я не знаком с wurstmeister изображениями, этот docker-compose основанна изображениях Confluent, которые я знаю:

    (редактор исказил мой yaml, вы можете найти здесь )

    ---
    version: '2'
    services:
    zookeeper:
        image: confluentinc/cp-zookeeper:latest
        environment:
        ZOOKEEPER_CLIENT_PORT: 2181
        ZOOKEEPER_TICK_TIME: 2000
    
    kafka:
        # "`-._,-'"`-._,-'"`-._,-'"`-._,-'"`-._,-'"`-._,-'"`-._,-'"`-._,-'"`-._,-
        # An important note about accessing Kafka from clients on other machines: 
        # -----------------------------------------------------------------------
        #
        # The config used here exposes port 29092 for _external_ connections to the broker
        # i.e. those from _outside_ the docker network. This could be from the host machine
        # running docker, or maybe further afield if you've got a more complicated setup. 
        # If the latter is true, you will need to change the value 'localhost' in 
        # KAFKA_ADVERTISED_LISTENERS to one that is resolvable to the docker host from those 
        # remote clients
        #
        # For connections _internal_ to the docker network, such as from other services
        # and components, use kafka:9092.
        #
        # See https://rmoff.net/2018/08/02/kafka-listeners-explained/ for details
        # "`-._,-'"`-._,-'"`-._,-'"`-._,-'"`-._,-'"`-._,-'"`-._,-'"`-._,-'"`-._,-
        #
        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
    

Отказ от ответственности: я работаю на Confluent

...