英文:
Go Lang and Labix mgo - getting EOF after subsequent requests
问题
我有一个类似的网络进程,代码如下:
func main() {
// mgo
mongoDatabase, err := mgopath.Connect(envMongoPath)
if err != nil {
log.Fatal(err)
}
r := mux.NewRouter()
// ....
r.HandleFunc("/apps/{app:.+}", stuffHandler(mongoDatabase)).Methods("GET")
http.Handle("/", r)
listen := fmt.Sprintf("%s:%s", host, port)
log.Fatal(http.ListenAndServe(listen, nil))
}
而 mgopath.Connect
的代码如下:
func Connect(mongoPath string) (*mgo.Database, error) {
dbConfig, err := url.Parse(mongoPath)
if err != nil {
return nil, err
}
log.Printf("Connecting to %s", dbConfig.Host)
sess, err := mgo.Dial(dbConfig.Host)
if err != nil {
return nil, err
}
dbName := dbConfig.Path
log.Printf("Using database %s", dbName)
if len(dbName) < 2 {
return nil, errors.New("No database name specified.")
}
dbName = dbConfig.Path[1:len(dbConfig.Path)]
return sess.DB(dbName), err
}
在代码的后面:
c := database.C("stuff")
err = c.Find(bson.M{"id": id}).One(&item) // 前1-2分钟正常工作,然后出现EOF错误
// c.Insert(), c.Update(), c.All()...
问题是,几分钟后,对 MongoDB 的所有查询都返回 EOF
错误。我必须重新启动进程才能使其正常工作。这个问题在 Mac 和 Windows 上都遇到过(在 Windows 上更频繁)。MongoDB 运行在 Docker 中,而 Docker 又运行在 boot2docker 中。已经进行了虚拟机端口转发(这就是为什么查询在一定时间内工作的原因)。
mgo 要求我每次查询时都要进行拨号吗?有没有一些我不知道的超时设置?
英文:
I have a web process, similar to
func main() {
// mgo
mongoDatabase, err := mgopath.Connect(envMongoPath)
if err != nil {
log.Fatal(err)
}
r := mux.NewRouter()
// ....
r.HandleFunc("/apps/{app:.+}", stuffHandler(mongoDatabase)).Methods("GET")
http.Handle("/", r)
listen := fmt.Sprintf("%s:%s", host, port)
log.Fatal(http.ListenAndServe(listen, nil))
}
while mgopath.Connect looks like
func Connect(mongoPath string) (*mgo.Database, error) {
dbConfig, err := url.Parse(mongoPath)
if err != nil {
return nil, err
}
log.Printf("Connecting to %s", dbConfig.Host)
sess, err := mgo.Dial(dbConfig.Host)
if err != nil {
return nil, err
}
dbName := dbConfig.Path
log.Printf("Using database %s", dbName)
if len(dbName) < 2 {
return nil, errors.New("No database name specified.")
}
dbName = dbConfig.Path[1:len(dbConfig.Path)]
return sess.DB(dbName), err
}
Somewhere down the road:
c := database.C("stuff")
err = c.Find(bson.M{"id": id}).One(&item) // First ~1-2 minutes work as expected, then I receive EOFs
// c.Insert(), c.Update(), c.All()...
The problem is, that after a couple of minutes, all queries to mongodb return the error EOF
. I have to restart the process to get things working again. Experienced both issues on Mac and (more frequently) on Windows. MongoDB runs inside of Docker, which in turn runs inside of boot2docker. VM Port forwarding have been done (that's why queries work for a certain amount of time).
Does mgo require me to dial every time I'm doing a query? Is there some timeout I don't know about?
答案1
得分: 4
答案可以在这里找到:https://groups.google.com/forum/#!topic/mgo-users/XM0rc6p-V-8
> 有两种简单的方法可以解决这个错误:
>
> 1)在会话上调用Refresh方法,这将使其丢弃(或者如果连接良好,则放回连接池)它正在持有的连接,并在需要时选择一个新连接。
>
> 2)不要使用单个会话,而是在需要新会话时调用session.Copy,然后在使用完毕后调用session.Close。这也意味着在必要时您将使用多个连接到数据库。
英文:
The answer can be found here: https://groups.google.com/forum/#!topic/mgo-users/XM0rc6p-V-8
> There are two easy ways to get rid of the error:
>
> 1) Call Refresh on the session, which makes it discard (or put back in
> the pool, if the connection is good) the connection it's holding, and
> pick a new one when necessary.
>
> 2) Instead of using a single session, use many by calling session.Copy
> when you need a new session, and then call session.Close when you're
> done with it. This will also mean you're using multiple connections to
> the database, when necessary.
答案2
得分: 1
session.Copy可能会创建许多与MongoDB的连接,在大型项目中,你可能会遇到"打开的文件太多"的问题,所以你可以尝试使用以下方法:
如果你的连接不稳定,它会自动调用session.refresh。
减少连接和减少错误,适用于重试策略。
英文:
session.Copy may create many many connections to mongodb, in big projects, you may got "too many files open", so you can try this:
this will auto call session.refresh if your connection is not stable.
less connection and less error, for retry policy.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论