处理MongoDB断开/重新连接节点

当我的MongoDB连接空闲了几分钟,下一个请求就结束了。 从mongo命令行客户端,它看起来像这样:

 > db.users.find() Sat Jan 12 23:42:35 Socket recv() errno:54 Connection reset by peer 107.22.25.25:47207 Sat Jan 12 23:42:35 SocketException: remote: 107.22.25.25:47207 error: 9001 socket exception [1] server [107.22.25.25:47207] Sat Jan 12 23:42:35 DBClientCursor::init call() failed Sat Jan 12 23:42:35 query failed : chowology.users {} to: ds047207.mongolab.com:47207 Error: error doing query: failed Sat Jan 12 23:42:35 trying reconnect to ds047207.mongolab.com:47207 Sat Jan 12 23:42:35 reconnect ds047207.mongolab.com:47207 ok 

我看到这个问题针对MongoHQ和MongoLab的沙箱实例。

下一个请求通过罚款,因为重新连接。 这是我的networking应用程序的一个问题,因为在几分钟的不活动之后,这个错误会在networking请求期间出现。 有两件事让我感到惊讶:

  1. MongoDB连接经常被频繁地销毁
  2. 驱动程序只是引发exception,而不是在重新连接后自动重试(我正在使用使用mongoose的连接mongo,而mongoose使用节点mongodb-native )。

这是其他人的经验吗? 这应该如何处理? 如果应用程序开发人员将他们的数据库操作包装在一些重试exception处理废话中,我会感到惊讶。

你想看看服务器对象的文档

http://mongodb.github.com/node-mongodb-native/api-generated/server.html#server

特别是可以设置keepAlive和连接超时的socketOptions。 默认情况下,keepalive是closures的,超时时间是0或从不,这意味着os默认套接字超时有效(从os到os不等)。 保持活跃状态​​,会在tcp套接字连接下暂时发送一个数据包,以保持活动状态。 有时候,防火墙configuration不好,在closures连接时不发送结束数据包,导致连接中断,这是monoglabs人们正在谈论的(通常不是老实说,他们是可怕的configuration)。

  1. 检查你的电脑是否不睡觉
  2. 检查你的路由器/防火墙是否没有空闲连接

第一个问题原来是我的电脑在不知不觉中睡觉,并断开networking连接。 这是一台新电脑,我没有意识到我没有禁用睡眠:-P

MongoLab的Jared帮我解决了这个问题,我很感激。 他说,通过防火墙时这种行为是常见的(正如他的评论中所build议的那样)。 所以一个testing就是绕过这个。

仍然通过我的路由器,几个小时闲置后我得到一个不同的错误:

 db.users.find() Sun Jan 13 14:55:02 Socket say send() errno:32 Broken pipe 107.22.25.25:47207 Error: 9001 socket exception [2] server [107.22.25.25:47207] Sun Jan 13 14:55:02 trying reconnect to ds047207.mongolab.com:47207 Sun Jan 13 14:55:02 reconnect ds047207.mongolab.com:47207 ok 

我将再次尝试从不通过我的路由器/防火墙的服务器。

驱动程序在当前操作中引发exception的行为是可以预料到的,因为丢弃的连接确实是一个例外情况。

更新 :当我绕过我的路由器时,这些问题都不会发生,也不会出现在我相信在Joyent数据中心中运行的Nodejitsu实例中。

我有同样的问题,我认为这是因为我在代理服务器后面访问互联网