英文:
Container cannot connect to RabbitMQ
问题
我有3个容器连接到RabbitMQ:1个容器(支付服务)作为发布者,2个容器(购物车和目录服务)作为消费者。它们都在同一个网络中,并使用Docker Compose运行。奇怪的是,支付和目录容器连接到RabbitMQ容器没有问题,而购物车服务的连接始终被拒绝。不确定是什么原因,因为在将我的服务容器化之前,这3个本地服务连接到RabbitMQ容器都没有问题。
可能的问题是购物车容器在RabbitMQ容器完成启动之前尝试连接了吗?
只在购物车容器中发生:
amqp.Dial dial tcp 192.168.96.3:5672: connect: connection refused
Docker Compose配置:
cart-service:
build:
context: .
dockerfile: ./build/cart/Dockerfile
networks:
- shopnetwork
ports:
- 50052:50052
env_file:
- .env
depends_on:
- catalog-service
- payment-service
- redis
- rabbitmq
catalog-service:
build:
context: .
dockerfile: ./build/catalog/Dockerfile
networks:
- shopnetwork
ports:
- 50051:50051
env_file:
- .env
depends_on:
- mongo1
- mongo2
- mongo3
- rabbitmq
payment-service:
build:
context: .
dockerfile: ./build/payment/Dockerfile
networks:
- shopnetwork
ports:
- 50053:50053
env_file:
- .env
depends_on:
- mongo1
- mongo2
- mongo3
- rabbitmq
rabbitmq:
image: rabbitmq:3.9.11-management
networks:
- shopnetwork
ports:
- 5672:5672
- 15672:15672
networks:
shopnetwork:
我的RabbitMQ连接初始化代码。支付、购物车和目录都使用相同的代码来建立连接(在第9行拨号时失败):
// NewRabbitMQ使用环境变量中定义的配置实例化RabbitMQ实例。
func NewRabbitMQ() (*Rabbitmq, error) {
username := os.Getenv("RABBITMQ_USERNAME")
password := os.Getenv("RABBITMQ_PASSWORD")
hostname := os.Getenv("RABBITMQ_HOST")
port := os.Getenv("RABBITMQ_PORT")
url := fmt.Sprintf("amqp://%s:%s@%s:%s/", username, password, hostname, port)
conn, err := amqp.Dial(url) // <----------------- 在这里失败
if err != nil {
return nil, fmt.Errorf("amqp.Dial %w", err)
}
ch, err := conn.Channel()
if err != nil {
return nil, fmt.Errorf("conn.Channel %w", err)
}
err = ch.ExchangeDeclare(
"tasks", // name
"topic", // type
true, // durable
false, // auto-deleted
false, // internal
false, // no-wait
nil, // arguments
)
if err != nil {
return nil, fmt.Errorf("ch.ExchangeDeclare %w", err)
}
if err := ch.Qos(
1, // prefetch count
0, // prefetch size
false, // global
); err != nil {
return nil, fmt.Errorf("ch.Qos %w", err)
}
return &Rabbitmq{
Conn: conn,
Channel: ch,
}, nil
}
我的RABBITMQ的.env文件:
RABBITMQ_USERNAME=guest
RABBITMQ_PASSWORD=guest
RABBITMQ_HOST=rabbitmq
RABBITMQ_PORT=5672
RABBITMQ_MANAGEMENT_PORT=15672
英文:
I have 3 containers that connect to RabbitMQ: 1 container (Payment service) as the publisher, and 2 containers (Cart and Catalog services) as consumers. They are all in the same network and run using Docker Compose. Weird thing is Payment and Catalog containers have no problems connecting to RabbitMQ container while Cart service connection is always refused. Not sure what's causing this, before containerizing my services all 3 local services had no issue connecting to RabbitMQ container.
Is it possible the issue is because Cart container tried to connect before RabbitMQ in its container finished starting up?
Happened in Cart container only:
amqp.Dial dial tcp 192.168.96.3:5672: connect: connection refused
Docker compose:
cart-service:
build:
context: .
dockerfile: ./build/cart/Dockerfile
networks:
- shopnetwork
ports:
- 50052:50052
env_file:
- .env
depends_on:
- catalog-service
- payment-service
- redis
- rabbitmq
catalog-service:
build:
context: .
dockerfile: ./build/catalog/Dockerfile
networks:
- shopnetwork
ports:
- 50051:50051
env_file:
- .env
depends_on:
- mongo1
- mongo2
- mongo3
- rabbitmq
payment-service:
build:
context: .
dockerfile: ./build/payment/Dockerfile
networks:
- shopnetwork
ports:
- 50053:50053
env_file:
- .env
depends_on:
- mongo1
- mongo2
- mongo3
- rabbitmq
rabbitmq:
image: rabbitmq:3.9.11-management
networks:
- shopnetwork
ports:
- 5672:5672
- 15672:15672
networks:
shopnetwork:
My rabbitmq connection initialization code. Payment, Cart, and Catalog all use the same codes for establishing the connection (failed when dialing on line 9):
// NewRabbitMQ instantiates the RabbitMQ instances using configuration defined in environment variables.
func NewRabbitMQ() (*Rabbitmq, error) {
username := os.Getenv("RABBITMQ_USERNAME")
password := os.Getenv("RABBITMQ_PASSWORD")
hostname := os.Getenv("RABBITMQ_HOST")
port := os.Getenv("RABBITMQ_PORT")
url := fmt.Sprintf("amqp://%s:%s@%s:%s/", username, password, hostname, port)
conn, err := amqp.Dial(url) // <----------------- FAILED HERE
if err != nil {
return nil, fmt.Errorf("amqp.Dial %w", err)
}
ch, err := conn.Channel()
if err != nil {
return nil, fmt.Errorf("conn.Channel %w", err)
}
err = ch.ExchangeDeclare(
"tasks", // name
"topic", // type
true, // durable
false, // auto-deleted
false, // internal
false, // no-wait
nil, // arguments
)
if err != nil {
return nil, fmt.Errorf("ch.ExchangeDeclare %w", err)
}
if err := ch.Qos(
1, // prefetch count
0, // prefetch size
false, // global
); err != nil {
return nil, fmt.Errorf("ch.Qos %w", err)
}
return &Rabbitmq{
Conn: conn,
Channel: ch,
}, nil
}
My .env for RABBITMQ:
RABBITMQ_USERNAME=guest
RABBITMQ_PASSWORD=guest
RABBITMQ_HOST=rabbitmq
RABBITMQ_PORT=5672
RABBITMQ_MANAGEMENT_PORT=15672
答案1
得分: 1
"guest"用户只能从本地主机连接。
因此,我们需要添加一个配置文件,以允许来自rabbitmq容器外部的guest用户访问。
rabbitmq.config的内容如下:
[
{rabbit,
[
{loopback_users, []},
]}
].
并将配置文件拉取到rabbitmq容器中:
rabbitmq:
image: rabbitmq:3.9.11-management
networks:
- shopnetwork
ports:
- 5672:5672
- 15672:15672
volumes:
- ./rabbitmq.config:/etc/rabbitmq/rabbitmq.config
英文:
"guest" user can only connect from localhost.
So we need to add a config file to enable the guest user access from outside rabbitmq container.
The contents of the rabbitmq.config:
[
{rabbit,
[
{loopback_users, []},
]}
].
and pull the config to rabbitmq container:
rabbitmq:
image: rabbitmq:3.9.11-management
networks:
- shopnetwork
ports:
- 5672:5672
- 15672:15672
volumes:
- ./rabbitmq.config:/etc/rabbitmq/rabbitmq.config
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论