Golang中使用MongoDB驱动遇到问题求帮助

Golang中使用MongoDB驱动遇到问题求帮助 大家好,

我在我的代码中使用了官方的 MongoDB Go 驱动程序,它一直运行良好,直到我决定使用 docker-compose 来启动我的 mongodb 和 go-app 容器。

我的代码构建正常,但每当我尝试访问我的 Go Web 应用程序的主页时,都会收到以下错误。

错误:

app        | 2020/07/14 13:19:00 server selection error: server selection timeout, current topology: { Type: Unknown, Servers: [{ Addr: localhost:27017, Type: Unknown, State: Connected, Average RTT: 0, Last error: connection() : dial tcp 127.0.0.1:27017: connect: connection refused }, ] }

Docker-Compose 文件:

version: '3.1'

services:

  mongodb:
    image: mongo
    container_name: mongodb
    restart: always
    ports:
          - 27017:27017
    environment:
      MONGO_INITDB_ROOT_USERNAME: root
      MONGO_INITDB_ROOT_PASSWORD: local
    command: mongod --bind_ip mongodb


  app:
    image: app:1.4
    container_name: app
    environment:
      - MONGO_URL=mongodb
    ports:
         - 80:8080
    depends_on:
      - mongodb
    restart: always

正在运行的 Docker 容器

docker ps
CONTAINER ID        IMAGE                COMMAND                  CREATED             STATUS              PORTS                      NAMES
d130336be71e        app:1.4   "/app/main"              4 minutes ago       Up 2 seconds        0.0.0.0:80->8080/tcp       app
dc57dd2de645        mongo                "docker-entrypoint.s…"   4 minutes ago       Up 2 seconds        0.0.0.0:27017->27017/tcp   mongodb

Go 函数

func GetSession() (*mongo.Client, error) {
	dbURL := os.Getenv("MONGO_URL")
	
	// Set client options
	clientOptions := options.Client()
	clientOptions.SetDirect(true).ApplyURI("mongodb://" + dbUser + ":" + dbPassword + "@" + dbURL +":27017/?connect=direct")

	// Connect to MongoDB
	client, err := mongo.Connect(context.TODO(), clientOptions)

	if err != nil {
		Logger(Fatal, err)
	}

	// Check the connection
	err = client.Ping(context.TODO(), nil)

	if err != nil {
		Logger(Fatal, err)
	}
	// Return successful connection
	return client, nil

}

故障排除

  1. 作为尝试找出问题的一部分,我查看了 Stackoverflow 上强调的类似问题,并尝试了以下选项:

    • 尝试在连接 URI 中使用 connect=direct
    • 尝试使用 SetDirect
    • 如我的 docker-compose 文件中所示,添加了 --bindip
  2. 我登录到 app 容器并尝试 ping mongodb,它成功了:

root@d130336be71e:/app# ping mongodb
PING mongodb (172.18.0.2) 56(84) bytes of data.
64 bytes from mongodb.app_default (172.18.0.2): icmp_seq=1 ttl=64 time=0.159 ms
64 bytes from mongodb.app_default (172.18.0.2): icmp_seq=2 ttl=64 time=0.200 ms
64 bytes from mongodb.app_default (172.18.0.2): icmp_seq=3 ttl=64 time=0.079 ms
64 bytes from mongodb.app_default (172.18.0.2): icmp_seq=4 ttl=64 time=0.087 ms
64 bytes from mongodb.app_default (172.18.0.2): icmp_seq=5 ttl=64 time=0.083 ms
^C
--- mongodb ping statistics ---
5 packets transmitted, 5 received, 0% packet loss, time 60ms
rtt min/avg/max/mdev = 0.079/0.121/0.200/0.050 ms

更多关于Golang中使用MongoDB驱动遇到问题求帮助的实战教程也可以访问 https://www.itying.com/category-94-b0.html

1 回复

更多关于Golang中使用MongoDB驱动遇到问题求帮助的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


问题出在连接URI的构造上。你的代码中使用了dbUserdbPassword变量,但这些变量没有在代码片段中定义,而且你的docker-compose中设置的用户名是root,密码是local

错误信息显示Go应用在尝试连接localhost:27017,这说明连接URI可能没有正确解析。以下是修正后的代码:

func GetSession() (*mongo.Client, error) {
    dbURL := os.Getenv("MONGO_URL")
    if dbURL == "" {
        dbURL = "mongodb" // 默认使用服务名
    }
    
    // 使用docker-compose中设置的环境变量
    dbUser := "root"
    dbPassword := "local"
    
    // 构建连接URI - 注意认证数据库是admin
    connectionURI := fmt.Sprintf("mongodb://%s:%s@%s:27017/?authSource=admin", 
        dbUser, dbPassword, dbURL)
    
    clientOptions := options.Client().ApplyURI(connectionURI)
    
    // 设置更长的超时时间用于容器环境
    ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
    defer cancel()
    
    client, err := mongo.Connect(ctx, clientOptions)
    if err != nil {
        return nil, fmt.Errorf("连接失败: %v", err)
    }
    
    // 测试连接
    err = client.Ping(ctx, nil)
    if err != nil {
        return nil, fmt.Errorf("ping失败: %v", err)
    }
    
    return client, nil
}

另外,确保你的docker-compose文件中MongoDB服务正确配置:

version: '3.8'

services:
  mongodb:
    image: mongo:latest
    container_name: mongodb
    restart: always
    ports:
      - "27017:27017"
    environment:
      MONGO_INITDB_ROOT_USERNAME: root
      MONGO_INITDB_ROOT_PASSWORD: local
    command: mongod --auth --bind_ip_all
    
  app:
    build: .
    container_name: app
    environment:
      - MONGO_URL=mongodb
    ports:
      - "8080:8080"
    depends_on:
      - mongodb
    restart: always

关键修改:

  1. MongoDB命令中添加了--auth启用认证
  2. 使用--bind_ip_all而不是--bind_ip mongodb
  3. 连接URI中添加了authSource=admin参数
  4. 设置了合理的连接超时时间

这样配置后,Go应用应该能正确连接到MongoDB容器。

回到顶部