Golang连接被拒绝问题排查与解决
Golang连接被拒绝问题排查与解决 我遇到了一个连接问题,连接被拒绝,问题出现在从一个Docker文件中的Go应用程序连接到另一个Docker文件中的MySQL时。
version: ‘3’ services: fullstack-mysql: container_name: db_mysql build: context: ./MySQL ports:
- 3306:3306 volumes:
- database_mysql:/var/lib/mysql networks:
- fullstack
app: container_name: golang_app env_file:
- ./Go/.env build: context: ./Go ports:
- 9000:9000 restart: on-failure volumes:
- api:/usr/src/app/ depends_on:
- fullstack-mysql networks:
- fullstack
phpmyadmin: image: phpmyadmin/phpmyadmin container_name: phpmyadmin_container env_file:
- ./MySQL/.env depends_on:
- fullstack-mysql environment:
- PMA_HOST=fullstack-mysql #注意这里的“mysql”。必须是你用作mysql服务的名称。
- PMA_USER=root
- PMA_PORT=3306
- PMA_PASSWORD=root ports:
- 9090:80 restart: always networks:
- fullstack
volumes: api: database_mysql:
networks: fullstack: driver: bridge
./Go/Dockerfile
FROM golang:alpine AS builder ENV GO111MODULE=on ENV MYSQL_PASSWORD=$(MYSQL_PASSWORD) ENV MYSQL_USER=$(MYSQL_USER) ENV MYSQL_DATABASE=$(MYSQL_DATABASE) ENV MYSQL_PORT=$(MYSQL_PORT) ENV MYSQL_DRIVER=$(MYSQL_DRIVER) RUN mkdir /app ADD . /app/ WORKDIR /app COPY ./structs.go . COPY ./handlers.go . COPY ./server.go . COPY ./favicon.ico . COPY ./assets /assets RUN go mod init stuff.com RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build $(ls -1 *.go) EXPOSE 9000 CMD [“go”, “run”, “.”]
./MySQL/Dockerfile
FROM mysql:8.0 ENV MYSQL_PASSWORD=$(MYSQL_PASSWORD) ENV MYSQL_USER=$(MYSQL_USER) ENV MYSQL_DATABASE=$(MYSQL_DATABASE) ENV MYSQL_PORT=$(MYSQL_PORT) ENV MYSQL_DRIVER=$(MYSQL_DRIVER) COPY test.sql /docker-entrypoint-initdb.d/test.sql EXPOSE 3306
./Go/main.go
func db() error {
//connStr:=config.mysqlUser+“:”+config.mysqlPassword+“[@tcp](/user/tcp)(db:”+config.mysqlHost+“:”+config.mysqlPort+“)/”+config.mysqlDB //Ping Error: dial tcp: lookup db:127.0.0.1:3306: no such host
connStr:=config.mysqlUser+“:”+config.mysqlPassword+“[@tcp](/user/tcp)(db:”+config.mysqlPort+“)/”+config.mysqlDB //Ping Error: dial tcp 23.195.69.108:3306: connect: connection refused
log.Println(connStr)
db, err := sql.Open(config.mysqlDriver, connStr)
if err != nil {
log.Println(whereami.WhereAmI(), err.Error())
} else {
log.Println(fmt.Sprintf(“%s”, db), whereami.WhereAmI())
}
defer db.Close()
err = db.Ping()
if err != nil {
log.Println("Ping Error: " + err.Error())
} else {
dbx.conn = db
}
log.Println(fmt.Sprintf(“%s”, dbx.conn), whereami.WhereAmI())
log.Println(fmt.Sprintf(“%T”, dbx.conn), whereami.WhereAmI())
return err
}
log.Println(connStr)->docker:docker@tcp(db:3306)/test_db
./Go/.env
MYSQL_ROOT_PASSWORD=root MYSQL_PASSWORD=docker MYSQL_USER=docker MYSQL_DATABASE=test_db MYSQL_HOST=fullstack-mysql MYSQL_PORT=3306 MYSQL_DRIVER=mysql
COOKIE_NAME=panda COOKIE_VALUE=123456987 COOKIE_MAX_AGE=0 COOKIE_PATH=/ COOKIE_HTTP_ONLY=true DOMAIN=127.0.0.1 PORT=:9000 API_PATH=/api/ API_VERSION=v1 APP_KEY=secret-sauce PROTOCOL=http://
.Mysql/.env
MYSQL_ROOT_PASSWORD=root MYSQL_PASSWORD=docker MYSQL_USER=docker MYSQL_DATABASE=test_db MYSQL_HOST=127.0.0.1 MYSQL_PORT=3306 MYSQL_DRIVER=mysql
更多关于Golang连接被拒绝问题排查与解决的实战教程也可以访问 https://www.itying.com/category-94-b0.html
更多关于Golang连接被拒绝问题排查与解决的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
连接被拒绝通常是由于网络配置或连接字符串错误导致的。从你的配置来看,主要问题在于Go应用程序连接MySQL时使用了错误的连接地址。
在你的main.go文件中,连接字符串构建有问题:
// 当前错误的连接字符串
connStr:=config.mysqlUser+":"+config.mysqlPassword+"@tcp(db:"+config.mysqlPort+")/"+config.mysqlDB
应该使用在docker-compose中定义的MySQL服务名称fullstack-mysql,而不是db:
// 正确的连接字符串
connStr := config.mysqlUser + ":" + config.mysqlPassword + "@tcp(fullstack-mysql:" + config.mysqlPort + ")/" + config.mysqlDB
另外,你的Go Dockerfile中环境变量设置有问题,应该从.env文件读取配置。修改./Go/Dockerfile:
FROM golang:alpine AS builder
ENV GO111MODULE=on
RUN mkdir /app
ADD . /app/
WORKDIR /app
COPY . .
RUN go mod init stuff.com
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o main .
EXPOSE 9000
CMD ["./main"]
在Go代码中,确保正确读取环境变量:
package main
import (
"database/sql"
"fmt"
"log"
"os"
_ "github.com/go-sql-driver/mysql"
)
type Config struct {
mysqlUser string
mysqlPassword string
mysqlHost string
mysqlPort string
mysqlDB string
mysqlDriver string
}
var config Config
func init() {
config = Config{
mysqlUser: getEnv("MYSQL_USER", "docker"),
mysqlPassword: getEnv("MYSQL_PASSWORD", "docker"),
mysqlHost: getEnv("MYSQL_HOST", "fullstack-mysql"),
mysqlPort: getEnv("MYSQL_PORT", "3306"),
mysqlDB: getEnv("MYSQL_DATABASE", "test_db"),
mysqlDriver: getEnv("MYSQL_DRIVER", "mysql"),
}
}
func getEnv(key, defaultValue string) string {
if value, exists := os.LookupEnv(key); exists {
return value
}
return defaultValue
}
func db() error {
// 正确的连接字符串
connStr := fmt.Sprintf("%s:%s@tcp(%s:%s)/%s",
config.mysqlUser,
config.mysqlPassword,
config.mysqlHost, // 应该是 "fullstack-mysql"
config.mysqlPort,
config.mysqlDB)
log.Println("Connection string:", connStr)
db, err := sql.Open(config.mysqlDriver, connStr)
if err != nil {
log.Println("Open error:", err.Error())
return err
}
defer db.Close()
// 设置连接池参数
db.SetMaxOpenConns(25)
db.SetMaxIdleConns(25)
db.SetConnMaxLifetime(5 * time.Minute)
err = db.Ping()
if err != nil {
log.Println("Ping Error:", err.Error())
return err
}
log.Println("Successfully connected to MySQL")
return nil
}
func main() {
// 等待MySQL服务启动
time.Sleep(5 * time.Second)
if err := db(); err != nil {
log.Fatal("Database connection failed:", err)
}
// 你的应用逻辑
}
还需要在docker-compose.yml中确保网络配置正确,app服务应该等待MySQL完全启动:
version: '3'
services:
fullstack-mysql:
container_name: db_mysql
build:
context: ./MySQL
ports:
- "3306:3306"
environment:
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: test_db
MYSQL_USER: docker
MYSQL_PASSWORD: docker
volumes:
- database_mysql:/var/lib/mysql
networks:
- fullstack
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
timeout: 20s
retries: 10
app:
container_name: golang_app
build:
context: ./Go
ports:
- "9000:9000"
restart: on-failure
volumes:
- api:/usr/src/app/
depends_on:
fullstack-mysql:
condition: service_healthy
networks:
- fullstack
environment:
MYSQL_HOST: fullstack-mysql
MYSQL_PORT: 3306
MYSQL_USER: docker
MYSQL_PASSWORD: docker
MYSQL_DATABASE: test_db
phpmyadmin:
image: phpmyadmin/phpmyadmin
container_name: phpmyadmin_container
depends_on:
- fullstack-mysql
environment:
PMA_HOST: fullstack-mysql
PMA_USER: root
PMA_PORT: 3306
PMA_PASSWORD: root
ports:
- "9090:80"
restart: always
networks:
- fullstack
volumes:
api:
database_mysql:
networks:
fullstack:
driver: bridge
关键点是:
- 使用正确的服务名称
fullstack-mysql而不是db - 添加健康检查确保MySQL完全启动后再连接
- 在app服务中明确设置环境变量
- 使用正确的连接字符串格式:
user:password@tcp(host:port)/database

