bestsource

목표 세션을 유지하기 위한 모범 사례

bestsource 2023. 7. 3. 23:01
반응형

목표 세션을 유지하기 위한 모범 사례

저는 현재 mgo lib가 포함된 mongodb를 웹 애플리케이션에 사용하고 있지만, 제가 사용하는 방식이 좋은 것인지 잘 모르겠습니다.

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
    }
}

그렇다면 모범 사례가 있을까요, 아니면 이 방법이 괜찮은가요?감사해요.

그런 글로벌 세션은 사용하지 않는 것이 좋습니다.대신 모든 데이터베이스 상호 작용을 담당하는 유형을 작성할 수 있습니다.예:

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 드라이버가 잘 작동합니다.또한 각 세션은 사용 중에 독립 소켓에 의해 지원되며, 독립적인 설정이 구성될 수 있으며 독립적인 오류 처리도 가능합니다.이러한 문제는 단일 글로벌 세션을 사용할 경우 결국 처리해야 합니다.

당신의 질문에 직접 대답하지는 않지만 mgo 세션 확인과 관련하여 mgo 호출 이후 연기/복구를 사용해야 합니다(심지어 mgo.회기의패닉.내가 아는 한 mgo 세션 상태(mgo godocs)를 확인할 수 있는 다른 방법은 없습니다.당신은 구스타보 니마이어의 제안을 사용하고 당신의 것에 방법을 추가할 수 있습니다.DataStore유형.

func (d *DataStore) EnsureConnected() {
    defer func() {
        if r := recover(); r != nil {
            //Your reconnect logic here.
        }
    }()

    //Ping panics if session is closed. (see mgo.Session.Panic())  
    d.Ping()
}

go 1.7과 함께, 웹 서버에서 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))
        })
    }

언급URL : https://stackoverflow.com/questions/26574594/best-practice-to-maintain-a-mgo-session

반응형