最近在使用mgo的过程中遇到了一些问题,总结标记一下。

1、关于mgo的连接池问题。相关的几个方法如下

Dial(url string) (*Session, error)
func (*Session) Clone() *Session
func (*Session) Copy() *Session

用以上三个方法得到的Session,使用完后需要Close(),如果不close的话,连接池中的session会一直增加,直到默认配置的4096。之后获取session的协程会sleep等待,直到有可用的session。业务端的表现就是程序挂死,类似死锁的表现😂。所以session用完后一定要defer close掉

2、针对1中提到的情况,写了个方法调用mgo Collection下对应的函数。

package main

import (
    "fmt"
    "gopkg.in/mgo.v2"
)

var (
    session *mgo.Session
)

func Session() *mgo.Session {
    if session == nil {
        var err error
        session, err = mgo.Dial("root:root@127.0.0.1:27017")
        if err != nil {
            panic(err)
        }
    }
    return session.Clone()
}

func Magic(database string, collection string, f func(*mgo.Collection) error) error {
    session := Session()
    defer func() {
        if session != nil {
            session.Close()
        }
    }()

    c := session.DB(database).C(collection)
    return f(c)
}

func main() {
    var m interface{}
    err := Magic("test", "test", func(c *mgo.Collection) error {
        return c.Find(nil).One(&m)
    })
    fmt.Println(err, m)
}

参考