首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在Go应用程序中使用MongoDb连接池

在Go应用程序中使用MongoDb连接池
EN

Stack Overflow用户
提问于 2019-12-31 10:19:59
回答 2查看 2.3K关注 0票数 1

我正在与Mongodb一起开发Golang应用程序。以前,我使用的是不需要池的db连接。因此,当一些流量进入时,我的db就会挂起或关闭。

然后我就了解了连接池。我研究过它,但我怀疑它是否与我的应用程序结构相匹配。

我在这里提供了一些来自我的应用程序的代码示例。

函数创建到db的连接:

代码语言:javascript
复制
func ConnectDb(merchantDb string) (mongoSession *mgo.Session) {
    mongoDBDialInfo := &mgo.DialInfo{
        Addrs:     []string{DatabaseIpPort},
        Username:  DbUsername,
        Password:  DbPassword,
        Source:    DbSource,
        Database:  merchantDb,
        Timeout:   60 * time.Second,
        PoolLimit: 4096,
    }
    mongoSession, err := mgo.DialWithInfo(mongoDBDialInfo)
    if err != nil {
        fmt.Printf("CreateSession: %s\n", err)
        defer mongoSession.Close()
        return mongoSession
    }
    mongoSession.SetMode(mgo.Monotonic, true)
    return mongoSession
}

连接到db的模型函数示例:

代码语言:javascript
复制
func (MerchantDb *MerchantDatabase) UpdateCustomer(uid int, query interface{}) (err error) {
    mongoSession := config.ConnectDb(MerchantDb.Database)
    defer mongoSession.Close()

    sessionCopy := mongoSession.Copy()
    defer sessionCopy.Close()

    getCollection := sessionCopy.DB(MerchantDb.Database).C("customers")
    err = getCollection.Update(bson.M{"uid": uid}, query)
    return err
}

我如何称呼这个函数:

代码语言:javascript
复制
type MerchantDatabase struct {
    Database string
}
merchantDb := MerchantDatabase{c.Keys["merchant_db"].(string)}
merchantDb.UpdateUser(7, bson.M{"$set": bson.M{"name": "john"})

和上面的代码一样,我对每个查询都使用了不同的模型函数&在每个模型函数中,使用mongodb建立了一个新的连接。

我的问题是:

  1. --我刚刚用现有的代码传递了PoolLimit。这就是连接池的工作方式吗?或者还有别的什么?
  2. 也在我的应用程序中,根据商人的说法,有多个数据库。这就是为什么我用数据库签名调用每个模型函数的原因,以便它能够查询特定的数据库。当连接池作为连接的缓存工作时,我感到困惑,它能使用一个商家的数据库连接来替代其他商家的数据库吗?如果是,如何使用连接池防止这种情况?
  3. 如何确定应用程序连接池的限制?

我将非常感谢收到这些答复。

谢谢!

EN

回答 2

Stack Overflow用户

发布于 2019-12-31 11:07:27

问题是您在每次UpdateCustomer的调用中创建了一个新的连接池,这既不方便也很昂贵。

您可以使用控制反转:

  • 在应用程序设置中准备连接池。将准备好的MerchantDatabase)
  • Use会话注入到模型的结构中(例如,在模型函数调用中的注入会话,以连接到相应的商人的DB.

)

注意:我假设所有商家的DB都托管在同一个mongo服务器节点或副本集中。

票数 5
EN

Stack Overflow用户

发布于 2019-12-31 14:49:07

我猜想这是从某个地方复制和粘贴的,但实际上并不了解它的用途或使用的原因:

代码语言:javascript
复制
func (MerchantDb *MerchantDatabase) UpdateCustomer(uid int, query interface{}) (err error) {
    mongoSession := config.ConnectDb(MerchantDb.Database)
    defer mongoSession.Close()

    sessionCopy := mongoSession.Copy()
    defer sessionCopy.Close()

    getCollection := sessionCopy.DB(MerchantDb.Database).C("customers")
    err = getCollection.Update(bson.M{"uid": uid}, query)
    return err
}

mongoSession.Copy()是如何获得一个新会话并正确使用池的方法。mongoSession实际上是一个池。但是在这里,您要创建一个连接,创建另一个连接,执行查询,然后关闭这两个连接。不能集中。

如果您查看mgo的任何教程,您会发现您应该创建一个主连接作为您的池,当您需要从池中连接时,您可以Copy()该主连接,根据需要使用该副本,然后关闭该副本。只有在应用程序退出时(通常情况下),才会关闭原始文件。原始的被用作工厂来创建池连接。

当我在谷歌上搜索"go mongo mgo连接池“时,我得到了这些顶级结果,这些结果解释了如何做到这一点:

https://www.ardanlabs.com/blog/2014/02/running-queries-concurrently-against.html

Connections pool in Go mgo package

然而,这在某种程度上是没有意义的--由于mgo文档和自述文件都处于状态,它已被废弃,不再维护。现在有一位来自蒙戈的官方司机:https://github.com/mongodb/mongo-go-driver

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59542753

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档