维护 mgo 会话的最佳实践

我目前正在使用带有 mgo lib 的 mongodb 用于 Web 应用程序,但我不确定我使用它的方式是否好..


package db


import (

    "gopkg.in/mgo.v2"

)


const (

    MongoServerAddr = "192.168.0.104"

    RedisServerAddr = "192.168.0.104"

)


var (

    MongoSession, err = mgo.Dial(MongoServerAddr)


    MDB  = MongoSession.DB("message")

    MCol = MDB.C("new")

    MSav = MDB.C("save")


    UDB  = MongoSession.DB("account")

    UCol = UDB.C("user")

)

我初始化 db 会话并创建接受集合和文档值的变量,因此当我需要查询集合时,我使用该变量来创建它。


像那样:


func UserExist(username string) bool {

    user := Users{}

    err := db.UCol.Find(bson.M{"username": username}).One(&user)

    if err != nil {

        return false

    } else {

        return true

    }

}

那么有没有最佳实践或者这个很好..?谢谢


慕码人8056858
浏览 191回答 3
3回答

胡说叔叔

我建议不要使用这样的全局会话。相反,您可以创建一个负责所有数据库交互的类型。例如:type DataStore struct {    session *mgo.Session}func (ds *DataStore) ucol() *mgo.Collection { ... }func (ds *DataStore) UserExist(user string) bool { ... }这种设计有很多好处。一个重要的是,它允许您同时进行多个会话,因此,例如,如果您有一个 http 处理程序,您可以创建一个本地会话,该会话由一个独立会话支持,仅用于该请求:func (s *WebSite) dataStore() *DataStore {    return &DataStore{s.session.Copy()}}    func (s *WebSite) HandleRequest(...) {    ds := s.dataStore()    defer ds.Close()    ...}在这种情况下,mgo 驱动程序表现良好,因为会话在内部缓存和重用/维护。每个会话在使用时也将由一个独立的套接字支持,并且可以配置独立的设置,并且还将具有独立的错误处理。如果您使用单个全局会话,这些是您最终必须处理的问题。

倚天杖

在 go 1.7 中,在 web 服务器上处理 mongo 会话的最惯用的方法是使用新的标准库包context编写一个中间件,该中间件可以在defer session.Close()调用请求上下文 Done() 时附加到。所以你不需要记得关闭AttachDeviceCollection = func(next http.Handler) http.Handler {&nbsp; &nbsp; &nbsp; &nbsp; return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; db, err := infra.Cloner()&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if err != nil {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; http.Error(w, err.Error(), http.StatusInternalServerError)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; collection, err := NewDeviceCollection(db)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if err != nil {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; db.Session.Close()&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; http.Error(w, err.Error(), http.StatusInternalServerError)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ctx := context.WithValue(r.Context(), DeviceRepoKey, collection)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; go func() {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; select {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; case <-ctx.Done():&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; collection.Session.Close()&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }()&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; next.ServeHTTP(w, r.WithContext(ctx))&nbsp; &nbsp; &nbsp; &nbsp; })&nbsp; &nbsp; }
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go