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

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

如何使用連接池將 mgo 會話轉換為 mongo-go-driver 客戶端?

如何使用連接池將 mgo 會話轉換為 mongo-go-driver 客戶端?

Go
忽然笑 2023-07-26 13:38:24
很久很久以前,當我們使用 mgo.v2 時,我們創建了一些包裝函數來復制會話、設置讀取首選項并返回該函數以供其他庫使用,例如func NewMonotonicConnection() (conn *Connection, success bool) {    conn := &Connection{        session: baseSession.Copy(),    }    conn.session.SetMode(mongo.Monotonic, true)    return conn, true}現在,我們只需在 init 函數中傳遞默認客戶端(使用 mongo.Connect 初始化并傳遞到連接單例中),然后像這樣使用:func NewMonotonicConnection() (conn *Connection, success bool) {    conn = defaultConnection    return conn, true}我的理解是,要利用連接池,您需要使用相同的客戶端(包含在 defaultConn 中),并且會話現在在 / .All()cursor 拆卸內部隱式處理。如果我在這里錯了,請糾正我。如果我們仍然可以在這些連接上設置 readpref(例如,在返回之前在此連接上設置 NearestMode),那就太好了,但是社區/標準的做法是什么?我知道我可以一遍又一遍地調用 mongo.Connect,但是那貴嗎?我可以創建不同的客戶端 - 每個客戶端都有不同的 readpref - 但我在想,如果在該連接上發生寫入,它永遠不會返回從從屬設備讀取。看起來我*可以顯式創建會話,但我不確定我應該或者在新驅動程序中顯式管理這些會話是否有任何影響。
查看完整描述

1 回答

?
qq_花開花謝_0

TA貢獻1835條經驗 獲得超7個贊

在這個任務中,我通過 mongo-go-driver 代碼庫學到了一些東西,我認為在結束這個問題之前我應該與世界分享這些東西。如果我錯了 - 請糾正我。

Connect()如果您想利用連接池,則不應一遍又一遍地調用??雌饋砻看握{用 Connect() 時都會創建一個新套接字。defer Close()這意味著隨著時間的推移,除非您每次都手動進行操作,否則存在套接字耗盡的風險。

All()在 mongo-go-driver 中,當您調用執行查詢時(例如),會話會在幕后自動處理。您可以*顯式地創建和拆除會話,但您不能使用我上面提出的單例方法來使用它,而不必更改所有調用方函數。這是因為您無法再在會話上調用查詢操作,而是必須在數據庫操作本身上使用 WithSession 函數來使用它

我意識到writeconcern,readprefreadconcern都可以設置為:

  • 客戶端級別(如果不覆蓋,這些是所有內容都將使用的默認值)

  • 會話級別

  • 數據庫級

  • 查詢級別

所以我所做的是創建數據庫選項并重載 *mongo.Database 例如:

// Database is a meta-helper that allows us to wrap and overload

// the standard *mongo.Database type

type Database struct {

    *mongo.Database

}


// NewEventualConnection returns a new instantiated Connection

// to the DB using the 'Nearest' read preference.

// Per https://github.com/go-mgo/mgo/blob/v2/session.go#L61

// Eventual is the same as Nearest, but may change servers between reads.

// Nearest: The driver reads from a member whose network latency falls within

// the acceptable latency window. Reads in the nearest mode do not consider

// whether a member is a primary or secondary when routing read operations;

// primaries and secondaries are treated equivalently.

func NewEventualConnection() (conn *Connection, success bool) {

    conn = &Connection{

        client: baseConnection.client,

        dbOptions: options.Database().

            SetReadConcern(readconcern.Local()).

            SetReadPreference(readpref.Nearest()).

            SetWriteConcern(writeconcern.New(

                writeconcern.W(1))),

    }


    return conn, true

}

// GetDB returns an overloaded Database object

func (conn Connection) GetDB(dbname string) *Database {

    dbByName := &Database{conn.client.Database(dbname, conn.dbOptions)}

}

這使我能夠利用連接池并保持與我們的代碼庫的向后兼容性。希望這對其他人有幫助。


查看完整回答
反對 回復 2023-07-26
  • 1 回答
  • 0 關注
  • 153 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

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

幫助反饋 APP下載

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

公眾號

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