我尝试使用Kafka @ Wurstmeister设置docker-compose。
场景: 我开发了多个微服务的体系结构。具体来说:我有一个Spring Boot应用程序,它将JSON发送到我的kafka代理。 Flask服务使用数据。 在docker外部运行整体思考时,此方法有效。我还可以将数据发送到docker中的kafka主题。
代码: 烧瓶:
KafkaHost = "kafka:9092"
def initkafka():
# connect to Kafka server and pass the topic we want to consume
consumer = KafkaConsumer("TEST",
group_id='view',
bootstrap_servers=[Constants.KafkaHost]
)
KafkaConsumer(auto_offset_reset='latest',
enable_auto_commit=False)
KafkaConsumer(value_deserializer=lambda m: json.loads(m.dedoce('utf-8')))
KafkaConsumer(consumer_timeout_ms=1000)
return consumer
Docker Compose:
zookeeper:
image: wurstmeister/zookeeper
ports:
- "2181:2181"
networks:
- test-net
kafka:
image: wurstmeister/kafka
ports:
- "9092:9092"
environment:
#KAFKA_ADVERTISED_HOST_NAME: 172.17.0.1
KAFKA_LISTENERS: PLAINTEXT://:9092
KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://172.17.0.1:9092
KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181
KAFKA_CREATE_TOPICS: "TEST:1:1"
volumes:
- /var/run/docker.sock:/var/run/docker.sock
depends_on:
- zookeeper
networks:
- test-net
错误
Traceback (most recent call last):
File "run.py", line 1, in <module>
from controller import Controller
File "/app/controller/Controller.py", line 27, in <module>
consumer = KafkaConfig.initkafka()
File "/app/config/KafkaConfig.py", line 16, in initkafka
enable_auto_commit=False)
File "/usr/local/lib/python3.6/site-packages/kafka/consumer/group.py", line 324, in __init__
self._client = KafkaClient(metrics=self._metrics, **self.config)
File "/usr/local/lib/python3.6/site-packages/kafka/client_async.py", line 221, in __init__
self.config['api_version'] = self.check_version(timeout=check_timeout)
File "/usr/local/lib/python3.6/site-packages/kafka/client_async.py", line 826, in check_version
raise Errors.NoBrokersAvailable()
kafka.errors.NoBrokersAvailable: NoBrokersAvailable
我认为这是环境配置的问题。我已经阅读了wurstmeister文档,但无法弄清楚需要进行哪些设置才能使烧瓶服务找到kafka代理。 日志显示kafka正在运行,并且创建了主题“ TEST”。 我是否需要配置侦听器例如说用ip和port在我的网络中会听kafka吗?因为在kafka docs advertised.listeners中被描述为
发布到ZooKeeper以便客户端使用的侦听器,如果与侦听器config属性不同。在IaaS环境中,这可能需要与代理绑定的接口不同。如果未设置,将使用侦听器的值。与侦听器不同,宣告0.0.0.0元地址无效。
答案 0 :(得分:0)
除非我弄错了,否则KAFKA_ADVERTISED_LISTENERS
的值必须与您在flask客户端中定义的kafka主机相同。因此,如果要从Docker容器内部连接到Kafka,则应具有KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://kafka:9092
。如果从主机进行连接,则应为KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://localhost:9092
。
或者,您可以省略KAFKA_ADVERTISED_LISTENERS
设置,而改为定义KAFKA_ADVERTISED_HOST_NAME: kafka
。
答案 1 :(得分:0)
所以我经历了@ cricket_007提到的this。现在情况比较清楚了,但是我仍然很难获得连接。 作为我的场景的回顾:我在同一个Docker Network中运行所有服务和消息代理。因此,无需进行外部连接。 在此博客条目中,提供了一个示例:
KAFKA_LISTENERS: LISTENER_BOB://kafka0:29092,LISTENER_FRED://localhost:9092
KAFKA_ADVERTISED_LISTENERS: LISTENER_BOB://kafka0:29092,LISTENER_FRED://localhost:9092
KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: LISTENER_BOB:PLAINTEXT,LISTENER_FRED:PLAINTEXT
KAFKA_INTER_BROKER_LISTENER_NAME: LISTENER_BOB
我想我知道此配置的含义。 就我而言,我认为我必须以这种方式进行更改:
KAFKA_LISTENERS: LISTENER_PY://kafka:9092
KAFKA_ADVERTISED_LISTENERS: LISTENER_PY://kafka:9092
KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: LISTENER_PY:PLAINTEXT
KAFKA_INTER_BROKER_LISTENER_NAME: LISTENER_PY
我猜不需要KAFKA_INTER_BROKER_LISTENER_NAME,因为我只有一名经纪人。但是,侦听器名称(LISTENER_PY)是否取决于我的Flask服务名称或其他任何属性?据我了解,我可以使用“ kafka”作为ip,因为我在docker-compose中将Kafka作为名为“ kafka”的服务运行。我尝试了这种配置,但仍然无法正常工作。我想知道它如何在我的spring服务中以生产者身份进行连接而不定义任何侦听器配置。