gopkg.in/mgo.v2中的并发性(Mongo,GO)



我希望在webapp中使用mongodb。

我可以有一个mgo.Session并在Web应用中同时使用它。例如在http.Handler

我应该致电Session.CopySession.Close->进行会话池。

在我读到的某个地方听起来很矛盾,我可以在mgo.Session内实现池,我可以同时使用会话,在其他地方我读到我需要CopyClose

mgo.Session是安全使用的。引用其文档:

所有会话方法都是并发安全的,可以从多个goroutines调用。

,但这并不意味着您不应该在拨号时获得的初始会话来通过调用Session.Copy()Session.Clone()并并行创建和使用更多。

是并发安全的,并从中受益更多,不会彼此排除(它们不是相互排斥的)。虽然您可能会从任意数量的goroutines中使用单个mgo.Session,但不会很好地扩展,但根本不会扩展。会话会自动管理连接池,甚至可能与多个服务器节点进行管理,但是如果您使用的是单个Session,则不会利用它。通过在每个请求开始时创建一个新的Session(如果需要),并在末尾正确关闭(使用Session.Close();最好使用defer),您正在利用可能同时使用多个连接的优势到多个服务器节点(如果有),从而更好地利用服务器资源;并获得更快的响应时间(包括数据库,最终来自您的HTTP最终用户)。致电Session.Close()不会关闭与服务器的基础连接,它将仅将连接放回池,准备被另一届会话接收。

还参见有关Session S:MGO的使用的相关问题 - 查询性能似乎始终如一(500-650ms)

调用DialDialWithTimeoutDialWithInfo将建立连接池。如果您需要多个会话,则需要调用session.copy.copy()或session.new(),session.copy()是首选的,因为它将保留该验证。这是一个示例:

可以说,您有一个UserService结构来满足所有用户数据库的需求。请注意,这是我头顶的,所以可能有一些语法错误,但这个想法就在那里。

type Userservice struct {
    DB *mgo.Session
}
func (s *Userservice) Create(u *User) error {
    sessionCopy := s.DB.Copy()
    defer sessionCopy.Close()
    db := sessionCopy.DB("test_db")
    col := db.C("users")
    if err := col.Insert(u); err != nil {
        return err
    }
}

最新更新