Golang中遇到Panic: dial tcp 192.168.160.2:3305: connect: connection refused错误求助

Golang中遇到Panic: dial tcp 192.168.160.2:3305: connect: connection refused错误求助 每次运行 docker-compose up 时,我都会遇到这个错误。

//错误

> $ docker-compose up --build
Creating network "bucket-api_fullstack" with driver "bridge"
Building bucket
Step 1/17 : FROM golang:1.15-alpine as builder
 ---> 3dae2ccc15b8
Step 2/17 : RUN mkdir /app
 ---> Using cache
 ---> 70dd1c583533
Step 3/17 : ADD . /app
 ---> Using cache
 ---> 4586c50cca46
Step 4/17 : WORKDIR /app
 ---> Using cache
 ---> c3a943c24b9e
Step 5/17 : RUN go clean --modcache
 ---> Using cache
 ---> 200b57f5142e
Step 6/17 : RUN go mod download
 ---> Using cache
 ---> 25e6672cddbe
Step 7/17 : RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o main ./src/
 ---> Using cache
 ---> 625a83d39c9d

Step 8/17 : FROM alpine:latest
 ---> e50c909a8df2
Step 9/17 : RUN apk --no-cache add ca-certificates
 ---> Using cache
 ---> 9fb84fe65803
Step 10/17 : RUN apk add --no-cache git make musl-dev go
 ---> Using cache
 ---> 81520138b2d7
Step 11/17 : COPY --from=builder /app/main .
 ---> Using cache
 ---> c285894862aa
Step 12/17 : ENV GOROOT /usr/lib/go
 ---> Using cache
 ---> c5a2790f18cb
Step 13/17 : ENV GOPATH /go
 ---> Using cache
 ---> 8fdf6d244cd1
Step 14/17 : ENV PATH /go/bin:$PATH
 ---> Using cache
 ---> a40c53d193c1
Step 15/17 : RUN mkdir -p ${GOPATH}/src ${GOPATH}/bin
 ---> Using cache
 ---> b199ed72e3f5
Step 16/17 : EXPOSE 8084
 ---> Using cache
 ---> 4ab9ad5a24af
Step 17/17 : CMD ["./main"]
 ---> Using cache
 ---> 4f1478c4b83f

Successfully built 4f1478c4b83f
Successfully tagged bucketapi:latest
Creating bucket-database ... done
Creating bucket-api      ... done
Attaching to bucket-database, bucket-api
bucket-api      | rbucket pagal!123 bucket-database 3305 rb_db
bucket-api      | panic: dial tcp 192.168.160.2:3305: connect: connection refused
bucket-api      |
bucket-api      | goroutine 1 [running]:
bucket-api      |
bucket-api      |       /app/src/datasources/mysql/bucket_db/bucket_db.go:51 +0x554
bucket-database | 2021-02-12 11:50:17+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 8.0.23-1debian10 started.
bucket-database | 2021-02-12 11:50:17+00:00 [Note] [Entrypoint]: Switching to dedicated user 'mysql'
bucket-database | 2021-02-12 11:50:17+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 8.0.23-1debian10 started.
bucket-database | 2021-02-12T11:50:18.393432Z 0 [System] [MY-010116] [Server] /usr/sbin/mysqld (mysqld 8.0.23) starting as process 1
bucket-database | 2021-02-12T11:50:18.941771Z 1 [System] [MY-013576] [InnoDB] InnoDB initialization has started.
bucket-database | 2021-02-12T11:50:23.269865Z 1 [System] [MY-013577] [InnoDB] InnoDB initialization has ended.
bucket-database | 2021-02-12T11:50:23.974635Z 0 [System] [MY-011323] [Server] X Plugin ready for connections. Bind-address: '::' port: 33060, socket: /var/run/mysqld/mysqlx.sock
bucket-database | 2021-02-12T11:50:24.336745Z 0 [System] [MY-010229] [Server] Starting XA crash recovery...
bucket-database | 2021-02-12T11:50:24.357326Z 0 [System] [MY-010232] [Server] XA crash recovery finished.
bucket-database | 2021-02-12T11:50:25.059647Z 0 [Warning] [MY-010068] [Server] CA certificate ca.pem is self signed.
bucket-database | 2021-02-12T11:50:25.060266Z 0 [System] [MY-013602] [Server] Channel mysql_main configured to support TLS. Encrypted connections are now supported for this channel.
bucket-database | 2021-02-12T11:50:25.191338Z 0 [Warning] [MY-011810] [Server] Insecure configuration for --pid-file: Location '/var/run/mysqld' in the path is accessible to all OS users. Consider choosing a different directory.
bucket-database | 2021-02-12T11:50:25.327133Z 0 [System] [MY-010931] [Server] /usr/sbin/mysqld: ready for connections. Version: '8.0.23'  socket: '/var/run/mysqld/mysqld.sock'
 port: 3306  MySQL Community Server - GPL.
bucket-api exited with code 2

这是我的 DOCKER-COMPOSE 文件

>  version: '3.8'
>
> services:
>   # MYSQL DATABASE DOCKER
>   bucket-mysql:
>     image: mysql:latest
>     container_name: bucket-database
>     command: --default-authentication-plugin=mysql_native_password
>     ports:
>       - "127.0.0.1:3305:3306"
>     environment:
>       MYSQL_ROOT_PASSWORD: "pagal!123"
>       MYSQL_USER: "rbucket"
>       MYSQL_PASSWORD: "root"
>       MYSQL_DATABASE: "rb_db"
>     networks:
>       - fullstack
>     volumes:
>       - database_mysql:/var/lib/mysql
>     restart: always
>     cap_add:
>       - SYS_NICE
>     healthcheck:
>       test: ["CMD-SHELL", "echo 'select 1' |mysql -u root -p'pagal!123' --silent"]
>       interval: 30s
>       timeout: 20s
>       retries: 6
>
>   #API DOCKER
>   bucket:
>     image: bucketapi
>     build: .
>     container_name: bucket-api
>     environment:
>       MYSQL_ROOT_PASSWORD: "pagal!123"
>       MYSQL_USER: "rbucket"
>       MYSQL_PASSWORD: "pagal!123"
>       MYSQL_DATABASE: "rb_db"
>       MYSQL_HOST: "bucket-database"
>       MYSQL_PORT: "3305"
>     ports:
>       - "8084:8084"
>     # restart: on-failure
>     # volumes:
>     #   - ./src:/usr/src/app/
>     depends_on:
>       - bucket-mysql
>     networks:
>       - fullstack
>
>
> volumes:
>     database_mysql:
>
> networks:
>   fullstack:
>     driver: bridge

这是我的 DOCKER 文件

> #Builder image build the go binary : Setting the alias as builder
>
> FROM golang:1.15-alpine as builder
>
> RUN mkdir /app
>
> # add this file directory to the image
>
> ADD . /app
>
> # directory where the source file execution takes place
>
> WORKDIR /app
>
> # RUN some go commands
>
> RUN go clean --modcache
>
> RUN go mod download
>
> RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o main ./src/
>
> # Our production image used to run our app
>
> FROM alpine:latest
>
> RUN apk --no-cache add ca-certificates
>
> RUN apk add --no-cache git make musl-dev go
>
> COPY --from=builder /app/main .
>
> # Configure GO
>
> ENV GOROOT /usr/lib/go
>
> ENV GOPATH /go
>
> ENV PATH /go/bin:$PATH
>
> RUN mkdir -p ${GOPATH}/src ${GOPATH}/bin
>
> EXPOSE 8084
>
> CMD ["./main"]

我从此文件中收到错误

> //client info
>
> var (
>
>     client *sql.DB
>
> )
>
> func init() {
>
>     // loaDerr := godotenv.Load()
>
>     // if loaDerr != nil {
>
>     //  log.Fatal("Error loading .env file")
>
>     // }
>
>     username := os.Getenv("MYSQL_USER")
>
>     password := os.Getenv("MYSQL_ROOT_PASSWORD")
>
>     host := os.Getenv("MYSQL_HOST")
>
>     port := os.Getenv("MYSQL_PORT")
>
>     schema := os.Getenv("MYSQL_DATABASE")
>
>     fmt.Println(username, password, host, port, schema)
>
>     dataSourceName := fmt.Sprintf(
>
>         "%s:%s@tcp(%s:%s)/%s?charset=utf8",
>
>         username,
>
>         password,
>
>         host,
>
>         port,
>
>         schema,
>
>     )
>
>     var err error
>
>     //connect to the database server
>
>     client, err = sql.Open("mysql", dataSourceName)
>
>     if err != nil {
>
>         panic(err)
>
>     }
>
>     //checking the connection
>
>     if connectionErr := client.Ping(); connectionErr != nil {
>
>         panic(connectionErr)
>
>     }
>
>     fmt.Println("Database connection is been established succesfully")
>
> }
>
> //GetClient : this method returns the connected client database
>
> func GetClient() *sql.DB {
>
>     return client
>
> }

更多关于Golang中遇到Panic: dial tcp 192.168.160.2:3305: connect: connection refused错误求助的实战教程也可以访问 https://www.itying.com/category-94-b0.html

11 回复

我之前尝试过,它总是给我同样的错误。

更多关于Golang中遇到Panic: dial tcp 192.168.160.2:3305: connect: connection refused错误求助的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


好的,Docker容器运行正常……感谢你的帮助 🙂

抱歉,skillian,但这对我没有帮助,谢谢。

我正在使用移动设备,建议你查阅“depends”的文档,以便让你的应用程序等待数据库启动。此外,与其因为数据库不可用而引发恐慌,你可能应该从你的应用程序中进行重试。

我从未使用过这个 wait 工具。

通常我只是执行一个 sleep 30

或者我直接在客户端添加一些适当的错误处理,使其能够以指数退避的方式重试连接到数据库。

NobbZ:

192.168.160.2

我认为这是 MySQL 容器的 IP 地址,因为我已经提到了附加了端口的 MySQL 容器名称。您能就这个问题给我提供一个参考吗?这对我将是巨大的帮助,谢谢。

我认为你可以尝试使用端口 3306 来连接 MySQL 容器。 就像你 ports 配置中最新的 ("3305:3306") 那样,你可能可以通过 <your_host>:3305<mysql_container_ip>:3306 来连接 MySQL 服务器。

niteeshDubey:

192.168.160.2

这个IP地址属于谁?它是否属于那个在你的程序已经退出后才首次有输出的数据库?

那么,让你的程序依赖于数据库容器,并且在启动你的应用之前添加一段充裕的休眠时间,因为 docker-compose 没有容器“就绪”的概念。

我不熟悉Docker,所以这可能不相关,但是:

niteeshDubey:

ports:
  - "127.0.0.1:3305:3306"

在我看来,这似乎意味着MySQL只会监听来自MySQL服务器本身的传入连接。在Docker中,有没有办法可以监听任何IP,或者监听Docker提供的IP(我认为Docker可以做到这一点)?或许直接用 ":3305:3306"

这个错误是因为你的Go应用在MySQL容器完全启动之前就尝试连接数据库。从日志可以看到,bucket-api容器在MySQL容器还在初始化时就尝试连接,导致连接被拒绝。

问题出现在depends_on只确保容器启动顺序,但不等待服务完全就绪。你需要让Go应用等待MySQL完全准备好再连接。

修改你的Go代码,添加重试逻辑:

package main

import (
    "database/sql"
    "fmt"
    "log"
    "os"
    "time"
    
    _ "github.com/go-sql-driver/mysql"
)

var (
    client *sql.DB
)

func init() {
    username := os.Getenv("MYSQL_USER")
    password := os.Getenv("MYSQL_ROOT_PASSWORD")
    host := os.Getenv("MYSQL_HOST")
    port := os.Getenv("MYSQL_PORT")
    schema := os.Getenv("MYSQL_DATABASE")
    
    dataSourceName := fmt.Sprintf(
        "%s:%s@tcp(%s:%s)/%s?charset=utf8",
        username,
        password,
        host,
        port,
        schema,
    )
    
    var err error
    maxRetries := 30
    retryInterval := 2 * time.Second
    
    for i := 0; i < maxRetries; i++ {
        client, err = sql.Open("mysql", dataSourceName)
        if err != nil {
            log.Printf("Failed to open database (attempt %d/%d): %v", i+1, maxRetries, err)
            time.Sleep(retryInterval)
            continue
        }
        
        err = client.Ping()
        if err != nil {
            log.Printf("Failed to ping database (attempt %d/%d): %v", i+1, maxRetries, err)
            client.Close()
            time.Sleep(retryInterval)
            continue
        }
        
        fmt.Println("Database connection established successfully")
        return
    }
    
    log.Fatalf("Failed to connect to database after %d attempts", maxRetries)
}

func GetClient() *sql.DB {
    return client
}

另外,确保你的docker-compose.yml中bucket服务等待MySQL健康检查通过:

version: '3.8'

services:
  bucket-mysql:
    image: mysql:latest
    container_name: bucket-database
    command: --default-authentication-plugin=mysql_native_password
    ports:
      - "127.0.0.1:3305:3306"
    environment:
      MYSQL_ROOT_PASSWORD: "pagal!123"
      MYSQL_USER: "rbucket"
      MYSQL_PASSWORD: "root"
      MYSQL_DATABASE: "rb_db"
    networks:
      - fullstack
    volumes:
      - database_mysql:/var/lib/mysql
    restart: always
    healthcheck:
      test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
      timeout: 20s
      retries: 10
      interval: 10s
      start_period: 40s

  bucket:
    image: bucketapi
    build: .
    container_name: bucket-api
    environment:
      MYSQL_ROOT_PASSWORD: "pagal!123"
      MYSQL_USER: "rbucket"
      MYSQL_PASSWORD: "pagal!123"
      MYSQL_DATABASE: "rb_db"
      MYSQL_HOST: "bucket-database"
      MYSQL_PORT: "3306"  # 注意这里应该是3306,不是3305
    ports:
      - "8084:8084"
    depends_on:
      bucket-mysql:
        condition: service_healthy
    networks:
      - fullstack

volumes:
  database_mysql:

networks:
  fullstack:
    driver: bridge

注意:在docker-compose中,bucket服务连接MySQL应该使用容器内部的端口3306,而不是映射到主机的3305。容器间通信使用服务名和内部端口。

回到顶部