Go MongoDB(mgo) - 不释放已关闭的连接

时间:2017-11-21 01:28:00

标签: database mongodb go

我的MongoDB数据库的活动连接数量正在快速增长。

我编写了一个代码来测试连接创建/关闭流程的工作原理。此代码总结了我在项目中使用mgo库的方式。

package main

import (
    "time"

    "fmt"

    "gopkg.in/mgo.v2"
)

func main() {
    // No connections
    // db.serverStatus().connections.current = 6

    mongoSession := connectMGO("localhost", "27017", "admin")
    // 1 new connection created
    //db.serverStatus().connections.current = 7

    produceDataMGO(mongoSession)
    produceDataMGO(mongoSession)
    produceDataMGO(mongoSession)
    produceDataMGO(mongoSession)
    // 4 new connections created and closed
    // db.serverStatus().connections.current = 7

    go produceDataMGO(mongoSession)
    go produceDataMGO(mongoSession)
    go produceDataMGO(mongoSession)
    go produceDataMGO(mongoSession)
    // 4 new connections created and closed concurrently
    // db.serverStatus().connections.current = 10

    time.Sleep(time.Hour * 24) // wait any amount of time
    // db.serverStatus().connections.current = 10
}

func connectMGO(host, port, dbName string) *mgo.Session {
    session, _ := mgo.DialWithInfo(&mgo.DialInfo{
        Addrs:    []string{fmt.Sprintf("%s:%s", host, port)},
        Timeout:  10 * time.Second,
        Database: dbName,
        Username: "",
        Password: "",
    })
    return session
}

func produceDataMGO(conn *mgo.Session) {
    dbConn := conn.Copy()
    dbConn.DB("").C("test").Insert("")
    dbConn.Close()
}

我发现了一件我不理解的非常奇怪的事情。行为在某种程度上是不同的,这取决于我们如何创建新连接(同步/异步)。

如果我们同步创建连接 - mongo在调用.Close()方法后立即关闭此新连接。

如果我们异步创建连接 - 即使在调用.Close()方法之后,mongo也会保持这个新连接的存在。

<击>

<击>
    <击>
  1. 为什么会这样?

  2. 还有其他强制关闭连接套接字的方法吗?

  3. 会在一段时间后自动关闭这些打开的连接吗?

  4. 有没有办法设置MongoDB可以将其池扩展到的连接数限制?
  5. 有没有办法在没有高负载的情况下在一定时间后设置自动截断?

1 个答案:

答案 0 :(得分:1)

这是连接池。当您“关闭”会话时,必然关闭;它可能只是返回池中重复使用。在同步示例中,它不需要扩展池;你一次只使用一个连接。在并发示例中,您一次使用多个连接,因此可能会确定它需要扩展池。我不会认为10个开放的连接值得关注。

尝试使用更大的测试 - 例如,10批10个goroutines - 然后看看有多少连接打开。如果你打开100个连接,就会出现问题;如果你有10~20,那么汇集工作正常。