亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

維護 mgo 會話的最佳實踐

維護 mgo 會話的最佳實踐

Go
慕碼人8056858 2021-08-23 17:49:20
我目前正在使用帶有 mgo lib 的 mongodb 用于 Web 應用程序,但我不確定我使用它的方式是否好..package dbimport (    "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    }}那么有沒有最佳實踐或者這個很好..?謝謝
查看完整描述

3 回答

?
胡說叔叔

TA貢獻1804條經驗 獲得超8個贊

我建議不要使用這樣的全局會話。相反,您可以創建一個負責所有數據庫交互的類型。例如:


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 驅動程序表現良好,因為會話在內部緩存和重用/維護。每個會話在使用時也將由一個獨立的套接字支持,并且可以配置獨立的設置,并且還將具有獨立的錯誤處理。如果您使用單個全局會話,這些是您最終必須處理的問題。


查看完整回答
反對 回復 2021-08-23
?
倚天杖

TA貢獻1828條經驗 獲得超3個贊

在 go 1.7 中,在 web 服務器上處理 mongo 會話的最慣用的方法是使用新的標準庫包context編寫一個中間件,該中間件可以在defer session.Close()調用請求上下文 Done() 時附加到。所以你不需要記得關閉


AttachDeviceCollection = func(next http.Handler) http.Handler {

        return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {

            db, err := infra.Cloner()

            if err != nil {

                http.Error(w, err.Error(), http.StatusInternalServerError)

                return

            }

            collection, err := NewDeviceCollection(db)


            if err != nil {

                db.Session.Close()

                http.Error(w, err.Error(), http.StatusInternalServerError)

                return

            }

            ctx := context.WithValue(r.Context(), DeviceRepoKey, collection)

            go func() {

                select {

                case <-ctx.Done():

                    collection.Session.Close()

                }

            }()


            next.ServeHTTP(w, r.WithContext(ctx))

        })

    }



查看完整回答
反對 回復 2021-08-23
  • 3 回答
  • 0 關注
  • 225 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號