gopkg.in/mgo.v2 (Mongo, Go) 中的并发
Concurrency in gopkg.in/mgo.v2 (Mongo, Go)
我想在用 Go 编写的 webapp 中使用 MongoDB。
我可以拥有一个 mgo.Session
并在网络应用程序中同时使用它吗?例如在 http.Handler
或者我应该调用 Session.Copy
和 Session.Close
-> 创建会话池。
这听起来很矛盾,我读到池已经在 mgo.Session
内部实现,我可以同时使用会话,而在其他地方我读到我需要 Copy
和 Close
。
调用Dial
或DialWithTimeout
或DialWithInfo
将建立连接池。如果您需要多个会话,则需要调用 session.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
}
}
mgo.Session
可以安全地同时使用。引用其文档:
All Session methods are concurrency-safe and may be called from multiple goroutines.
但这并不意味着您不应该通过调用 Session.Copy()
or Session.Clone()
在拨号时获得的初始会话中并行创建和使用它们。
并发安全和从使用更多并发中获益并不相互排斥(它们不是互斥)。虽然您可以使用来自任意数量的 goroutine 的单个 mgo.Session
,但这不会很好地扩展,根本不会扩展 。会话自动管理一个连接池,甚至可能连接到多个服务器节点,但如果您使用单个 Session
,您就没有利用它。通过在每个请求的开头创建一个新的 Session
(如果需要),并在结尾正确关闭它(使用 Session.Close()
;最好使用 defer
调用),您正在潜在地同时使用多个连接的优势,可能到多个服务器节点(如果可用),从而更好地利用服务器资源;并获得更快的响应时间(从数据库到最终到您的 HTTP 最终用户)。调用 Session.Close()
不会关闭与服务器的底层连接,它只会将连接放回池中,准备好被另一个会话拾取。
另请参阅有关使用 Session
s 的相关问题:
我想在用 Go 编写的 webapp 中使用 MongoDB。
我可以拥有一个 mgo.Session
并在网络应用程序中同时使用它吗?例如在 http.Handler
或者我应该调用 Session.Copy
和 Session.Close
-> 创建会话池。
这听起来很矛盾,我读到池已经在 mgo.Session
内部实现,我可以同时使用会话,而在其他地方我读到我需要 Copy
和 Close
。
调用Dial
或DialWithTimeout
或DialWithInfo
将建立连接池。如果您需要多个会话,则需要调用 session.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
}
}
mgo.Session
可以安全地同时使用。引用其文档:
All Session methods are concurrency-safe and may be called from multiple goroutines.
但这并不意味着您不应该通过调用 Session.Copy()
or Session.Clone()
在拨号时获得的初始会话中并行创建和使用它们。
并发安全和从使用更多并发中获益并不相互排斥(它们不是互斥)。虽然您可以使用来自任意数量的 goroutine 的单个 mgo.Session
,但这不会很好地扩展,根本不会扩展 。会话自动管理一个连接池,甚至可能连接到多个服务器节点,但如果您使用单个 Session
,您就没有利用它。通过在每个请求的开头创建一个新的 Session
(如果需要),并在结尾正确关闭它(使用 Session.Close()
;最好使用 defer
调用),您正在潜在地同时使用多个连接的优势,可能到多个服务器节点(如果可用),从而更好地利用服务器资源;并获得更快的响应时间(从数据库到最终到您的 HTTP 最终用户)。调用 Session.Close()
不会关闭与服务器的底层连接,它只会将连接放回池中,准备好被另一个会话拾取。
另请参阅有关使用 Session
s 的相关问题: