使用mongodb副本集来服务我的应用服务器时,我遇到了一个问题,即4个应用服务器和2个mongo从节点之间的TCP连接持续增加,直到2个mongo从节点停止服务 .

环境

  • 操作系统:Ubuntu 14.04 64位,适用于mongodb服务器和应用服务器

  • mongodb:v3.0.9,副本设置为1个主设备,2个从设备和1个仲裁设备

  • app:4个服务器集群,由golang编写,带有mongodb驱动程序gopkg.in/mgo.v2

详情

1.通常我们在每个从节点上有大约55个连接 .

以下是来自其中一个从节点的正常日志:

2017-03-12T03:01:41.165 0800 I NETWORK [initandlisten]连接从127.0.0.1:43775接受#1537161(现已 Build 55个连接)2017-03-12T03:01:41.188 0800 I ACCESS [conn1537161]已成功通过身份验证admin admin on admin 2017-03-12T03:01:41.193 0800 I NETWORK [conn1537161] end connection 127.0.0.1:43775(54个连接现已开通)2017-03-12T03:01:41.938 0800 I NETWORK [conn1537152] end connection 10.162 .xxx.xxx:49334(现在有53个连接)2017-03-12T03:01:41.938 0800我从10.162.xxx.xxx:49345#1537162接受网络[initandlisten]连接(现已 Build 54个连接)2017-03-12T03 :01:41.958 0800我访问[conn1537162]在本地2017-03-12T03:01:42.256 0800成功验证为主__system我从127.0.0.1:43776接受了NETWORK [initandlisten]连接#1537163(现已 Build 55个连接)2017- 03-12T03:01:42.279 0800 I ACCESS [conn1537163]在管理员2017-03-12T03:01:42.284 0800 I NETWORK [conn1537163]成功通过身份验证]结束连接127.0.0.1:43776(现已 Build 54个连接)2017-03-12T03:01:42.721 0800我访问[conn1401659]在线成功在线认证2017-03-12T03:01:47.243 0800 I NETWORK [conn1537154] ]结束连接10.251.xxx.xxx:34844(53个连接现已开启)

2.在某天早上3点02分左右,2个从节点的连接开始增加,每分钟每节点可能有5-15个连接 .

但是mongo主节点并没有什么不寻常之处 . 请注意,在此期间我们的应用服务器访问次数少于日光 . 来自上述同一从节点的异常日志:

2017-03-12T03:05:59.301 0800我从10.171.xxx.xxx:33377接受网络[initandlisten]连接#1537221(现已打开86个连接)2017-03-12T03:06:01.484 0800 I NETWORK [conn1537215]结束连接120.26.xxx.xxx:48190(85个连接现已开启)2017-03-12T03:06:01.487 0800我从120.26.xxx.xxx:48203#1537222接受网络[initandlisten]连接(现已开通86个连接)2017-03 -12T03:06:01.508 0800 I ACCESS [conn1537222]在本地2017-03-12T03:06:05.464 0800上成功验证为主__system我从10.168.xxx.xxx:51008#1537223接受了NETWORK [initandlisten]连接(现在87个连接) open)2017-03-12T03:06:11.231 0800 I ACCESS [conn1537213]在线成功在线认证2017-03-12T03:06:12.289 0800 I NETWORK [conn1537216] end connection 10.162.xxx.xxx:49427(86连接现已打开)

3.直到早上8点37分,奴隶节点终于停止了服务 .

2017-03-12T08:37:44.764 0800我从10.171.xxx.xxx:37444接受网络[initandlisten]连接#1571431(现已开通32306连接)2017-03-12T08:37:44.773 0800我成功[conn1571430]在线认证为在线2017-03-12T08:37:44.786 0800 I NETWORK [initandlisten] pthread_create失败:错误:11资源暂时不可用2017-03-12T08:37:44.786 0800 I NETWORK [initandlisten]无法创建新的线程,关闭连接2017-03-12T08:37:45.290 0800 I NETWORK [initandlisten]连接从10.171.xxx.xxx:37445接受#1571432(32306连接现已打开)2017-03-12T08:37:45.290 0800 I NETWORK [ initandlisten] pthread_create失败:错误:11资源暂时不可用2017-03-12T08:37:45.290 0800 I NETWORK [initandlisten]无法创建新线程,关闭连接

4.即使mongo节点之间的心跳也会崩溃 .

2017-03-12T08:37:57.000 0800 I REPL [ReplicationExecutor]对xxx.xxx.xxx.xxx:27017的心跳请求出错; UnknownError发送命令{replSetHeartbeat:“rs1”,pv:1,v:5,from:“xxx.xxx.xxx.xxx:27018”,fromId:1,checkEmpty:false} on database admin over network to xxx.xxx . xxx.xxx:27017收到异常抛出boost :: thread_resource_error

5.最后我重新启动了2个mongo从节点,一切顺利 .

6.要及时恢复应用服务,不再需要有关mongo节点或应用服务器的站点状态 . 只有两个线索如下 .

  • mongo从节点上的TCP连接迅速增加(但主节点也是正常的) .

  • 从app服务器到mongo slave节点的读取操作得到i / o超时(从3:02开始) .

我的猜测和调查

- mongodb slave节点出错了

假设来自mongodb slave节点的任何错误都会停止读取操作,这会导致app服务器的i / o超时;和app服务器认为池中没有连接到从节点不可用,因此尝试打开与从节点的新连接 . 但遗憾的是,无法正常 Build 连接,因此继续打开新的连接 .

- 应用服务器的mgo驱动程序连接池泄漏 .

但每个应用服务器只使用两个会话 . 详细地说,我在init()期间获取会话,并将它们用于db读/写操作 . 我无法弄清楚泄漏 . 这是我获得会话的代码:

func init() {  
          ...some code... 

          session, err := mgo.Dial(url)  
          if err != nil {...handle error...}  

          strongSession = session.Copy()  
          strongSession.SetMode(mgo.Strong, true)  
          strongSession.SetSafe(&mgo.Safe{})  

          eventualSession = session  
          eventualSession.SetMode(mgo.Eventual, true)  
          eventualSession.SetSafe(&mgo.Safe{})  

          ...some code...  
        }

如果问题是由mgo驱动程序的连接池泄漏引起的,我可以假设一些驱动程序gopkg.in/mgo.v2的池管理错误吗?

我的困惑

这个问题在我的现场环境中,几天前和两个月前发生了两次,同一时间段从凌晨3点到8点30分 .

我真的想过,如果mongo服务器和app服务器上的任何任务,但什么都没发现 .

我挖了日志,搜索谷歌和stackoverflow几天关键字,如“mgo连接池”,“mongo无法创建新线程”,“mongo连接增加”等等,但遗憾的是我不知道如何调查进一步这个问题 .

真的很感激任何人都可以给一些建议~~

非常感谢~~