【背景】没有并发的时候,Mongodb使用正常,当模拟多人并发访问(tps 100,不算高)所有功能接口的时候,4核cpu的mongo进程升到100%(理论上应该是接近400%),3分钟之后,查询接口开始变慢,响应时间高达20s
【思路】第一个想到了加索引,实际上数据库并不大,topic集合 和reply集合分别只有3万数据,在数据量大的情况下加索引才有优势
【解决】从数据库的链接入手,把mongdb的GlobalSession用一个实例改为每次拷贝副本操作,用完即关闭副本
【结果】再次用loadRunner做并发测试,所有接口响应时间都在1秒之内,快的几十毫秒,性能提示非常显著,cpu使用率升到340%
【代码】
*******************************通用部分 初始化*********************************
package db
import (
"chpkg.in/qiniu/log.v1"
"gopkg.in/mgo.v2"
"../config"
)
var GlobalSession *mgo.Session
func init() {
var err error
GlobalSession, err = mgo.Dial(config.Cfg.MgoAddr)
if err != nil {
log.Fatalln(err)
return
}
GlobalSession.SetMode(mgo.Monotonic, true)
GlobalSession.SetPoolLimit(config.Cfg.MongoPoolLimit)
Coll = GlobalSession.DB(config.Cfg.MgoDB).C(config.Cfg.MgoColl)
}
*******************************老代码*********************************
声明
// Coll is globle collection of binding
var Coll *mgo.Collection
func GetColl() *mgo.Collection {
if GlobalSession.Ping() != nil {
GlobalSession.Refresh()
log.Debug("refreshed GlobalSession")
Coll = GlobalSession.DB(config.Cfg.MgoDB).C(config.Cfg.MgoColl)
}
return Coll
}
调用
// 存在多用户绑定同一微信关系
if err := db.GetColl().Find(bson.M{"openid": u.OpenId}).All(&docs); err != nil {
log.Warn("FindBindByOpenId: ", err)
return ErrNoBinding
}
*******************************新代码*********************************
声明
func GetColl2(session *mgo.Session) *mgo.Collection {
return session.DB(config.Cfg.MgoDB).C(config.Cfg.MgoColl)
}
调用
func ReceiveGift(giftId bson.ObjectId) *Result {
session := db.GlobalSession.Copy()
defer session.Close()
err := db.GetColl2(session).UpdateId(giftId, bson.M{"$set": bson.M{"status": "1", "receiveTime": time.Now().Format("2006-01-02 15:04:05")}})
if err != nil {
re := Result{Status: false, Code: "-9999"}.Handle()
re.Msg += err.Error()
return re
}
return nil
}