Golang中Mgo会话每次都会创建新连接的问题
Golang中Mgo会话每次都会创建新连接的问题
func main() {
session, err := mgo.Dial("mongodb://localhost")
if err != nil {
panic(err)
}
defer session.Close()
db := session.DB("mydatabase")
result := bson.M{}
err = db.Run("serverStatus", &result)
if err != nil {
panic(err)
}
fmt.Println(result)
}
每当我执行 session.copy().DB(dbname) 时,db.serverStatus 的连接数都在增加,我需要避免这种情况。
更多关于Golang中Mgo会话每次都会创建新连接的问题的实战教程也可以访问 https://www.itying.com/category-94-b0.html
1 回复
更多关于Golang中Mgo会话每次都会创建新连接的问题的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
在Mgo中,每次调用session.Copy()确实会创建一个新的连接池,这可能导致数据库连接数不断增加。为了避免这种情况,您应该重用现有的会话或使用连接池机制。
以下是几种解决方案:
1. 使用全局会话并复用
var globalSession *mgo.Session
func init() {
session, err := mgo.Dial("mongodb://localhost")
if err != nil {
panic(err)
}
globalSession = session
}
func getDBSession() *mgo.Session {
return globalSession.Copy()
}
func main() {
session := getDBSession()
defer session.Close()
db := session.DB("mydatabase")
result := bson.M{}
err := db.Run("serverStatus", &result)
if err != nil {
panic(err)
}
fmt.Println(result)
}
2. 使用连接池配置
func main() {
session, err := mgo.Dial("mongodb://localhost")
if err != nil {
panic(err)
}
defer session.Close()
// 配置连接池
session.SetPoolLimit(100) // 设置最大连接数
session.SetMode(mgo.Monotonic, true)
// 复用会话
for i := 0; i < 10; i++ {
go func(i int) {
localSession := session.Copy()
defer localSession.Close()
db := localSession.DB("mydatabase")
result := bson.M{}
err := db.Run("serverStatus", &result)
if err != nil {
fmt.Printf("Error in goroutine %d: %v\n", i, err)
return
}
fmt.Printf("Goroutine %d completed\n", i)
}(i)
}
time.Sleep(2 * time.Second)
}
3. 使用单例模式管理会话
type MongoDBManager struct {
session *mgo.Session
}
var instance *MongoDBManager
var once sync.Once
func GetMongoDBManager() *MongoDBManager {
once.Do(func() {
session, err := mgo.Dial("mongodb://localhost")
if err != nil {
panic(err)
}
session.SetPoolLimit(50)
instance = &MongoDBManager{session: session}
})
return instance
}
func (m *MongoDBManager) GetSession() *mgo.Session {
return m.session.Copy()
}
func main() {
manager := GetMongoDBManager()
session := manager.GetSession()
defer session.Close()
db := session.DB("mydatabase")
result := bson.M{}
err := db.Run("serverStatus", &result)
if err != nil {
panic(err)
}
fmt.Println(result)
}
4. 直接使用原始会话(适用于简单场景)
func main() {
session, err := mgo.Dial("mongodb://localhost")
if err != nil {
panic(err)
}
defer session.Close()
// 直接使用原始会话,不调用Copy()
db := session.DB("mydatabase")
result := bson.M{}
err = db.Run("serverStatus", &result)
if err != nil {
panic(err)
}
fmt.Println(result)
}
关键点:
session.Copy()会创建新的连接池,应该谨慎使用- 在并发环境中,使用连接池限制最大连接数
- 对于大多数用例,直接使用原始会话或复用少量会话副本即可
- 记得在每个goroutine结束时调用
session.Close()来释放连接

