Go语言和Labix mgo – 在连续请求后出现EOF错误。

huangapple go评论90阅读模式
英文:

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(&quot;/apps/{app:.+}&quot;, stuffHandler(mongoDatabase)).Methods(&quot;GET&quot;)
	http.Handle(&quot;/&quot;, r)

	listen := fmt.Sprintf(&quot;%s:%s&quot;, 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(&quot;Connecting to %s&quot;, dbConfig.Host)
	sess, err := mgo.Dial(dbConfig.Host)
	if err != nil {
		return nil, err
	}

	dbName := dbConfig.Path
	log.Printf(&quot;Using database %s&quot;, dbName)
	if len(dbName) &lt; 2 {
		return nil, errors.New(&quot;No database name specified.&quot;)
	}

	dbName = dbConfig.Path[1:len(dbConfig.Path)]
	return sess.DB(dbName), err
}

Somewhere down the road:

c := database.C(&quot;stuff&quot;)
err = c.Find(bson.M{&quot;id&quot;: id}).One(&amp;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的连接,在大型项目中,你可能会遇到"打开的文件太多"的问题,所以你可以尝试使用以下方法:

https://github.com/ti/mdb

如果你的连接不稳定,它会自动调用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:

https://github.com/ti/mdb

this will auto call session.refresh if your connection is not stable.

less connection and less error, for retry policy.

huangapple
  • 本文由 发表于 2015年5月7日 04:04:31
  • 转载请务必保留本文链接:https://go.coder-hub.com/30086489.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定