事情的开始是这样的:
我在学习某个项目的时候,需要在docker中创建kafka容器。当我创建容器完毕后,执行golang的程序,发现报错:panic: cannot create Kafka producer: kafka: client has run out of available brokers to talk to: dial tcp: lookup kafka: no such host
原因如下:
我需要访问的地址为:kafka:9092,这里需要golang程序与kafka容器在同一个docker网络中,无法通过本机网络直接访问docker中的kafka服务。因为kafka服务并没有暴露端口给外部。
当我想到大致方向之后,和chatGPT确认了下详细思路,chatGPT给到的回复如下:
当您在macOS主机上直接运行Go程序,而该程序尝试访问Docker容器内的Kafka服务(如通过kafka:9092),它会遇到DNS解析问题,因为kafka这个主机名只在Docker内部网络中有效。
为了使您的Go程序能够正确访问Kafka服务,有几种解决方案:
方案1:在Docker容器内运行Go程序
将您的Go程序也放在Docker容器中运行,这样它就能和Kafka服务在同一个Docker网络中通信。可以使用Docker Compose来管理多容器应用。
Dockerfile
首先,创建一个Dockerfile来构建您的Go程序容器。
Dockerfile
使用官方的Go镜像作为基础镜像
FROM golang:1.18
设置工作目录
WORKDIR /app
将当前目录中的所有文件复制到工作目录中
COPY . .
编译Go程序
RUN go build -o myapp
运行可执行文件
CMD [“./myapp”]
docker-compose.yml
然后,更新您的docker-compose.yml文件,包含您的Go应用程序服务。
yaml
version: '3.8'
services:
zookeeper:
image: confluentinc/cp-zookeeper:7.3.1
logging:
driver: json-file
restart: unless-stopped
environment:
ZOOKEEPER_CLIENT_PORT: 2181
networks:
- kafka-net
kafka:
image: confluentinc/cp-kafka:7.3.1
logging:
driver: json-file
restart: unless-stopped
depends_on:
- zookeeper
environment:
KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181
KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://kafka:9092
KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1
KAFKA_AUTO_CREATE_TOPICS_ENABLE: "true"
ports:
- "9092:9092"
networks:
- kafka-net
myapp:
build: .
depends_on:
- kafka
networks:
- kafka-net
networks:
kafka-net:
构建和启动
构建和启动您的Docker Compose服务。
sh
docker-compose up --build
方案2:通过主机网络连接Kafka服务
如果您希望继续在本地主机上运行Go程序,可以在Kafka服务中配置主机网络,使Kafka服务在主机上暴露其端口,然后通过主机名访问Kafka。
更新docker-compose.yml
更新您的docker-compose.yml文件,将Kafka服务的KAFKA_ADVERTISED_LISTENERS环境变量配置为主机地址,并暴露端口。
yaml
version: '3.8'
services:
zookeeper:
image: confluentinc/cp-zookeeper:7.3.1
logging:
driver: json-file
restart: unless-stopped
environment:
ZOOKEEPER_CLIENT_PORT: 2181
networks:
- kafka-net
kafka:
image: confluentinc/cp-kafka:7.3.1
logging:
driver: json-file
restart: unless-stopped
depends_on:
- zookeeper
environment:
KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181
KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://localhost:9092
KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: PLAINTEXT:PLAINTEXT
KAFKA_INTER_BROKER_LISTENER_NAME: PLAINTEXT
KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1
ports:
- "9092:9092"
networks:
- kafka-net
networks:
kafka-net:
在本地运行Go程序
在本地运行Go程序时,确保它连接到localhost:9092。
go
var (
brokers = []string{"localhost:9092"}
consumeTopic = "events"
publishTopic = "events-processed"
logger = watermill.NewStdLogger(
true, // debug
false, // trace
)
marshaler = kafka.DefaultMarshaler{}
)
// 其他代码…
通过这两种方式之一,您可以确保您的Go程序能够正确连接到Kafka服务。第一种方式更为推荐,因为它确保所有服务都在相同的网络环境中运行,从而避免网络配置问题。

3518




被折叠的 条评论
为什么被折叠?



