我希望在Go中使用webapp中的MongoDB。gopkg.in/mgo.v2中的并发(Mongo,Go)
我可以有一个mgo.Session
并在网络应用程序中同时使用它。例如在http.Handler
或者我应该叫Session.Copy
和Session.Close
- >使会话池。
这听起来有点矛盾,我读到的那个池已经在mgo.Session
里面实现了,我可以同时使用会话,在其他地方我读到我需要Copy
和Close
。
我希望在Go中使用webapp中的MongoDB。gopkg.in/mgo.v2中的并发(Mongo,Go)
我可以有一个mgo.Session
并在网络应用程序中同时使用它。例如在http.Handler
或者我应该叫Session.Copy
和Session.Close
- >使会话池。
这听起来有点矛盾,我读到的那个池已经在mgo.Session
里面实现了,我可以同时使用会话,在其他地方我读到我需要Copy
和Close
。
该mgo.Session
是安全的并发使用。从其文档引用:
所有会话方法都是并发安全的,可以从多个goroutines调用。
但是,这并不意味着你不应该创建和使用更多的人并行,通过调用Session.Copy()
或Session.Clone()
,在上拨号时获得的初始会话。
并发安全,并从中受益更多的使用不排除对方(他们不是互斥)。虽然您可以从任意数量的例程中使用单个mgo.Session
,但这不会很好地扩展,但不会根据来缩放。会话会自动管理一个连接池,甚至可以连接到多个服务器节点,但如果您使用的是单个Session
,那么您没有充分利用这一点。通过在每个请求开始时创建一个新的Session
(如果需要),并在最后正确关闭它(使用Session.Close()
;最好使用defer
进行调用),您可能正在利用可能同时使用多个连接的可能性,可能到多个服务器节点(如果可用),从而更好地利用服务器资源;并获得更快的响应时间(无论是从数据库,最终到您的HTTP最终用户)。调用Session.Close()
不会关闭到服务器的底层连接,它只会将连接放回池中,准备被另一个会话接收。
另请参阅相关问题使用Session
s:mgo - query performance seems consistently slow (500-650ms)
调用Dial
或DialWithTimeout
或DialWithInfo
将建立连接池。如果您需要多个会话,则需要调用session.Copy()或session.New(),因为会保留auth,所以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
}
}