You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Docker容器内Go应用连接RabbitMQ失败求助

Docker环境下Go应用无法连接RabbitMQ的解决方案

问题背景

我编写了一个测试RabbitMQ的Go应用,同时使用Docker Compose管理Go应用和RabbitMQ服务。RabbitMQ能正常启动并访问管理面板,但Go应用始终报错:
024/01/22 13:16:33 Failed to connect to RabbitMQ: dial tcp 127.0.0.1:5672: connect: connection refused

相关代码与配置

Go应用代码

package main

import (
    "log"
    "time"

    "github.com/streadway/amqp"
)

func failOnError(err error, msg string) {
    if err != nil {
        log.Printf("%s: %s", msg, err)
    }
}

func main() {
    var conn *amqp.Connection
    var err error

    for i := 0; i < 5; i++ {
        conn, err = amqp.Dial("amqp://dev:test@rabbitmq:5672/")
        if err != nil {
            continue
        }
        log.Println(err)
        time.Sleep(5 * time.Second)
    }

    if err != nil {
        log.Printf("Failed to connect to RabbitMQ: %v", err)
    }

    ch, err := conn.Channel()
    failOnError(err, "Failed to open a channel")
    defer ch.Close()

    q, err := ch.QueueDeclare(
        "hello", // name
        false,   // durable
        false,   // delete when unused
        false,   // exclusive
        false,   // no-wait
        nil,     // arguments
    )
    failOnError(err, "Failed to declare a queue")

    body := "Hello World!"
    err = ch.Publish(
        "",     // exchange
        q.Name, // routing key
        false,  // mandatory
        false,  // immediate
        amqp.Publishing{
            ContentType: "text/plain",
            Body:        []byte(body),
        })
    log.Printf(" [x] Sent %s", body)
    failOnError(err, "Failed to publish a message")

    msgs, err := ch.Consume(
        q.Name, // queue
        "",     // consumer
        true,   // auto-ack
        false,  // exclusive
        false,  // no-local
        false,  // no-wait
        nil,    // args
    )
    failOnError(err, "Failed to register a consumer")

    forever := make(chan bool)

    go func() {
        for d := range msgs {
            log.Printf("Received a message: %s", d.Body)
        }
    }()

    log.Printf(" [*] Waiting for messages. To exit press CTRL+C")
    <-forever
}

Dockerfile

FROM golang:latest

LABEL maintainer="Anatoliy"

WORKDIR /app

COPY go.mod go.sum ./

RUN go mod download

COPY . .

RUN go build -o main .

EXPOSE 8080

CMD ["./main"]

docker-compose.yml

version: '3.9'
services:
  app:
    build: .
    ports:
      - "8080:8080"
    depends_on:
      rabbitmq:
        condition: service_healthy
  rabbitmq:
    image: "rabbitmq:3-management"
    hostname: "rabbit"
    environment:
      RABBITMQ_DEFAULT_USER: dev
      RABBITMQ_DEFAULT_PASS: test
    ports:
      - "5672:5672"
      - "15672:15672"
    healthcheck:
      test: ["CMD", "rabbitmqctl", "status"]
      interval: 30s
      timeout: 10s
      retries: 5

问题原因

在Docker Compose默认网络中,容器通过服务名称或容器主机名进行DNS解析。你的代码中指定了rabbitmq作为连接主机,但报错显示连接127.0.0.1,说明存在以下问题:

  1. RabbitMQ服务的主机名与代码中的连接主机不匹配(当前RabbitMQ主机名是rabbit,代码用的是rabbitmq)
  2. 重试逻辑存在缺陷,可能导致连接成功后仍执行错误分支
  3. 可能存在镜像缓存,容器运行的是旧版代码

修复方案

1. 统一RabbitMQ的服务名与主机名

修改docker-compose.yml中RabbitMQ的hostname为rabbitmq,确保与服务名一致,这样代码中的连接字符串amqp://dev:test@rabbitmq:5672/可以正确解析:

rabbitmq:
  image: "rabbitmq:3-management"
  hostname: "rabbitmq" # 修改为与服务名一致
  environment:
    RABBITMQ_DEFAULT_USER: dev
    RABBITMQ_DEFAULT_PASS: test
  ports:
    - "5672:5672"
    - "15672:15672"
  healthcheck:
    test: ["CMD", "rabbitmqctl", "status"]
    interval: 30s
    timeout: 10s
    retries: 5

2. 优化重试逻辑

原代码中重试成功后仍会打印err(此时为nil),且延迟放在循环内导致不必要等待,修改为:

for i := 0; i < 5; i++ {
    conn, err = amqp.Dial("amqp://dev:test@rabbitmq:5672/")
    if err == nil {
        log.Println("Connected to RabbitMQ successfully")
        break
    }
    log.Printf("Connection attempt %d failed: %v", i+1, err)
    time.Sleep(2 * time.Second)
}

3. 强制重新构建镜像

避免缓存导致容器运行旧代码:

docker-compose build --no-cache app
docker-compose down && docker-compose up -d

4. 验证网络连通性

进入Go应用容器,测试与RabbitMQ的网络连通性:

docker exec -it <app-container-name> /bin/bash
ping rabbitmq

如果能ping通,说明网络配置正常。

验证

启动服务后查看Go应用日志:

docker-compose logs app

若看到Connected to RabbitMQ successfully和[x] Sent Hello World!,则说明连接成功。

内容的提问来源于stack exchange,提问作者Anatoliy Krapotkin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 00:08:16