首页 > 解决方案 > 连接到远程 mongo 服务器工作正常,但是通过 Go 连接时,它给出了错误:超出了上下文截止日期

问题描述

我正在使用以下 ssh 隧道命令连接到远程 mongo 服务器:

ssh -i document-db-tun.pem -L 27017:docdb.cluster-cf.us-east-2.docdb.amazonaws.com:27017 ubuntu@ec2-111-111-111-111.us-east-2.compute.amazonaws.com -N

在本地使用 mongo 命令连接到 mongo 服务器也可以正常工作。

在此处输入图像描述

但是当我尝试使用 golang 代码在本地连接它时,它会抛出Mongo connection ckeck failed. Err: context deadline exceeded错误。

const (
    mongoTimeout = time.Second * 10
)

func initMongo() {
    mongoConf := common.Conf.ServiceConfig.Databases.Mongo

    ctx, _ := context.WithTimeout(context.Background(), mongoTimeout)
    uri := fmt.Sprintf("mongodb://127.0.0.1:27017")
    if common.IsSentryEnabled() {
        sentry.AddBreadcrumb(&sentry.Breadcrumb{
            Message:  fmt.Sprintf("Connecting to mongo server at: '%v'", uri),
            Category: common.SENTRY_CAT_REPO,
            Level:    sentry.LevelInfo,
        })
    }
    client := options.Client().
        SetReadPreference(readpref.SecondaryPreferred()).
        SetAppName("catalog").
        SetMaxConnIdleTime(time.Microsecond * 100000).
        SetAuth(options.Credential{
            Username: mongoConf.Username,
            Password: mongoConf.Password,
        }).
        ApplyURI(uri)

    pureMongoClient, err := mongo.Connect(ctx, client)
    if err != nil {
        if common.IsSentryEnabled() {
            sentry.AddBreadcrumb(&sentry.Breadcrumb{
                Message:  "Error connecting to mongo",
                Category: common.SENTRY_CAT_REPO,
                Level:    sentry.LevelFatal,
            })
            sentry.ConfigureScope(func(scope *sentry.Scope) {
                scope.SetTags(map[string]string{
                    common.SENTRY_SCOPE_KEY: common.SENTRY_SCOPE_MONGO,
                    common.SENTRY_TYPE_KEY:  common.SENTRY_TYPE_DB,
                })
            })
            sentry.CaptureException(err)
            sentry.Flush(time.Second * 5)
        }

        panic(fmt.Sprintf("Failed to establish mongo connection. Err: %v ", err))
    }

    err = pureMongoClient.Ping(ctx, readpref.Primary())
    if err != nil {
        if common.IsSentryEnabled() {
            sentry.AddBreadcrumb(&sentry.Breadcrumb{
                Message:  "Mongo connection ckeck failed",
                Category: common.SENTRY_CAT_REPO,
                Level:    sentry.LevelFatal,
            })
            sentry.ConfigureScope(func(scope *sentry.Scope) {
                scope.SetTags(map[string]string{
                    common.SENTRY_SCOPE_KEY: common.SENTRY_SCOPE_MONGO,
                    common.SENTRY_TYPE_KEY:  common.SENTRY_TYPE_DB,
                })
            })
            sentry.CaptureException(err)
            sentry.Flush(time.Second * 5)
        }

        panic(fmt.Sprintf("Mongo connection ckeck failed. Err: %v ", err))
    }

    mongoDB := pureMongoClient.Database(mongoConf.Dbname)

    dbManager.MongoDB = &MGODatabase{
        Database: mongoDB,
    }
}

代码中使用的用户名和密码是连接到远程服务器所需的。使用 golang 代码连接到远程 mongo 服务器时可能会出现什么问题?

标签: mongodbgoamazon-ec2

解决方案


以下是一些可能的问题

  • 端口问题
    您需要检查端口是否打开,并允许从任何地方进行连接。如果您使用的是 Linux(Ubuntu),请检查防火墙设置sudo ufw status verbose。如果防火墙被禁用,那就没问题了。

  • VM 端口访问
    还允许 VM 级别的端口。如果您使用的是 Amazon Lightsail,则必须明确允许该端口授予远程客户端访问权限以建立连接。

在此处输入图像描述

  • Docker 容器
    如果您的应用程序和 MongoDB 作为 Docker 容器部署到远程服务器并且您无法与 DB 建立连接,那么可能的解决方案是Docker Network
    • 创建自己的 Docker 网络
    • 创建 MongoDB 容器和名称容器,例如mongodb
    • 将 MongoDB 添加到您的网络
    • 将 Web 应用程序添加到您的网络
    • 尝试通过容器名称使用 Web 应用程序连接到 MongoDB 容器。
// Set client options
    clientOptions := options.Client().ApplyURI("mongodb://mongodb:27017") 
    clientOptions = clientOptions.SetMaxPoolSize(100)

推荐阅读