Reputation: 826
My MongoDB database has a fast-growing amount of active connections.
I wrote a code to test how connection creation/closing flow works. This code sums up how I use the mgo
library in my project.
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()
}
I detected a pretty weird thing that I don't understand. Behaviour is somehow different depending on how we create new connections (sync/async).
If we create connection synchronously - mongo closes this new connection immediately after calling .Close()
method.
If we create connection asynchronously - mongo keeps this new connection alive even after calling .Close()
method.
Why is it so?
Is there any other way to force-close connection socket?
Will it auto-close these open connections after a certain amount of time?
Upvotes: 0
Views: 1745
Reputation: 46572
It's connection pooling. When you "close" a session, it isn't necessarily closed; it may just be returned to the pool for re-use. In the synchronous example, it doesn't need to expand the pool; you're only using one connection at a time. In the concurrent example, you're using several connections at a time, so it may decide it does need to expand the pool. I would not consider 10 open connections to be cause for concern.
Try it with a larger test - say, 10 batches of 10 goroutines - and see how many connections are open afterward. If you have 100 connections open, something has gone wrong; if you have 10~20, then pooling is working correctly.
Upvotes: 2