Go語言mgo使用情況

2021-08-21 11:05:02 字數 4301 閱讀 5562

本文重點介紹mgo使用,僅簡單介紹mongodb。

mongdb簡單介紹

注意: 上圖已經告知我們mongo不支援事務,在開發專案應用時,想要保證資料的完整性請考慮關係型資料庫(經典例子銀行轉賬)。 mongo提供了許多原子操作,比如文件的儲存,修改,刪除等,都是原子操作。所謂原子操作就是要麼這個文件儲存到mongodb,要麼沒有儲存到mongodb,不會出現查詢到的文件不完整的情況。

mgo 是 mongodb 的 go 語言驅動包。

mgo官網:

mgo方案一

package mgo

import

( "flag"

"gopkg.in/mgo.v2"

"log"

"study/conf"

)var session *mgo.session

var database *mgo.database

func init

()*/

filename := flag.string("config", "./conf/config.json", "path to configuration file")

flag.parse()

config := &conf.configurationdatabase{}

config.load(*filename)

var err error

dialinfo := &mgo.dialinfo,

direct: false,

timeout: time.second * 1,

poollimit: 4096, // session.setpoollimit }

//建立乙個維護套接字池的session

session, err = mgo.dialwithinfo(dialinfo)

if err != nil

session.setmode(mgo.monotonic, true)

//使用指定資料庫

database = session.db(config.database)

}func getmgo

() *mgo.session

func getdatabase

() *mgo.database

func geterrnotfound

() error

這裡的 session 能夠和 mongodb 集群中的所有server通訊。

session設定的模式分別為:

//個人專案部分**

type user struct

func register

(password string, username string)

(err error)

)*/ err = con.insert(&user)

return

}func finduser(username string) (user, error) 型別)進行

//條件篩選,達到文件查詢的目的

/* 對應mongo命令列

db.user.find()*/

if err := con.find(bson.m).one(&user); err != nil

}return user, nil

}

通過find()可以進行單個或者全部的查詢,並且可以進行分頁處理。下面為簡單**展示:

con.find(nil).limit(5).skip(0).all(&user)

package models

import (

"gopkg.in/mgo.v2/bson"

"study/library/mgo"

"time"

)type diary struct

//通過uid查詢本作者文章,並且顯示文章作者名字

func finddiary(uid string) (inte***ce{}, error) },

},}]).pretty()

*/pipeline := bson.m},

bson.m},

bson.m},

}pipe := con.pipe(pipeline)

var data inte***ce{}

err := pipe.all(&data)

if err != nil

return data, nil

}func modifydiary(id, title, content string) (err error) ,

)*/err = con.update(bson.m, bson.m})

return

}

mgo更新方法很多,如批量更新con.updateall(selector, update),更新或插入資料con.upsert(selector, update)

思路一會兒

mgo方案二

思考: session 會被全域性使用,當在實際的程式中,我們可以開啟goroutine 來處理每個連線,多個goroutine 可以通過 session.clone() 來建立或復用連線,使用完成之後通過 session.close() 來關閉這個連線。當併發很高時,看起來可以提高效率。

下面部分**修改 :

import (

"flag"

"gopkg.in/mgo.v2"

"log"

"study/conf"

)var session *mgo.session

var config *conf.configurationdatabase

func init

() config.load(*filename)

var err error

dialinfo := &mgo.dialinfo,

direct: false,

timeout: time.second * 1,

poollimit: 4096, // session.setpoollimit

}session, err = mgo.dialwithinfo(dialinfo)

if err != nil

session.setmode(mgo.monotonic, true)

}type sessionstore struct

//獲取資料庫的collection

func (d * sessionstore) c(name string) *mgo.collection

//為每一http請求建立新的datastore物件

func new sessionstore() * sessionstore

return ds

}func (d * sessionstore) close()

func geterrnotfound() error

對查詢進行了修改

func finduser

(username string)

(user, error)

).one(&user); err != nil

}return user, nil

}

mgo方案一和二測試:

使用boom進行併發測試,並在每個 goroutine 裡面sleep 5秒,這樣是讓連線暫時不釋放,就可以看到 mgo 方案二 會不斷建立新連線,方案一不會建立新連線。可以使用mongo shell 的db.serverstatus().connections來檢視連線數。

mgo方案一測試連線數: 1000 併發:mongo 3個連線 5000 併發:mongo 3個連線。

mgo方案二測試連線數: 1000 併發:mongo 500多個連線 5000 併發:mongo 1400多個連線。

測試結果:mgo方案一和方案二在併發下,效率差不多。

可能性,由於資料少或者處理的單個mongo無法看出效果。

由於目前自己專案只使用了乙個mongo,後期使用多個mongo進行或在大量資料下測試。如果大家有什麼好的建議,提出來進行學習思考。

推薦學習:

官方部落格詳講了mgo併發處理,如下:

ExecutorService使用情況

1 executorservice是是乙個介面,繼承了executor 2 而executor亦是乙個介面,該介面只包含了乙個方法void execute runnable command 3 executors 該類是乙個輔助類,此包中所定義的 executor executorservice s...

前端This使用情況

一 普通函式的this指向window。二 物件方法中this指向呼叫者。三 建構函式中this。1 function newperson name,age const p1 new person 張三 18 return的內容為基本資料型別為p1,return的內容為引用資料型別為其本身 cons...

檢測USB使用情況

此方法放在任何地方,都可以正常.procedure tform1.usb var msg tmessage const dbt devicearrival 8000 dbt deviceremovecomplete 8004 dbt devnodes changed 0007 begin case ...