多个应用服务器上的MongoDB连接失败

Rus*_*anN 7 go mongodb mgo

我们有mongodb和gogo的mgo驱动程序.除应用程序(golang二进制文件)之外,还有两个连接到mongodb的应用程序服务器.Mongodb作为副本集运行,每个服务器根据副本的当前状态连接两个主服务器或辅助服务器.

我们SocketException handling request, closing client connection: 9001 socket exception在其中一个mongo服务器上经历过(导致我们的应用程序与mongodb连接死亡.之后,副本集继续正常运行,但我们的第二台服务器(错误未发生)连接已死亡同样.

在golang日志中,它表现为:

read tcp 10.10.0.5:37698-\u003e10.10.0.7:27017: i/o timeout

为什么会这样?如何防止这种情况?

据我所知,mgo通过url连接到整个副本(它通过单个实例的url检测整个拓扑)但是为什么在其中一个服务器上连接的dy使其在第二个服务器上被杀死?

编辑:

  1. 使用的完整包路径 "gopkg.in/mgo.v2"
  2. 不幸的是不能在这里分享mongo文件.但除了socketexecption mongo日志不包含任何有用的东西.有一些锁定争用的迹象表明锁定获取时间很长一段时间,但除此之外没什么
  3. MongoDB有时会做一些重型索引,但最近并没有出现任何异常的峰值,所以它不会超出正常范围

icz*_*cza 3

首先,mgo您正在使用的驱动程序:gopkg.in/mgo.v2由 Gustavo Niemeyer 开发(托管于https://github.com/go-mgo/mgo)不再维护。

相反,请使用社区支持的 fork github.com/globalsign/mgo。这个不断得到修补和发展。

它的变更日志包括:“改进的连接处理”,这似乎与您的问题直接相关。

其详细信息可以在此处阅读https://github.com/globalsign/mgo/pull/5,它指向原始拉取请求https://github.com/go-mgo/mgo/pull/437

如果 mongoServer 无法拨号服务器,它将关闭所有活动的套接字,无论它们当前是否正在使用。有两个缺点:

  • 飞行中的请求将被粗暴地中断。

  • 所有套接字同时关闭,并且可能同时拨打服务器。海量拨号请求(高并发场景)中的任何偶然失败都会使所有套接字再次关闭,并重复......(它发生在我们的生产环境中)

所以我认为当前正在使用的套接字应该在空闲后关闭。

请注意,它github.com/globalsign/mgo具有向后兼容的 API,它基本上只是添加了一些新的东西/功能(除了修复和补丁之外),这意味着您应该能够仅更改导入路径,并且所有内容都应该可以正常工作,而无需进一步更改。