我正在使用 Nodejs 和 mongoDB - 并且遇到一些连接问题。
好吧,实际上是“唤醒”问题!它连接得很好 - 速度 super 快,我对结果总体很满意。
我的问题:如果我有一段时间不使用连接(我说暂时,因为时间范围变化超过 5 分钟),它似乎会停止。我没有触发断开连接事件 - 它只是挂起。
最终我得到了类似 Error: failed to connect to [ * .mongolab.com: * ] - ( * = masked value) 的响应
应用程序快速重启,连接再次恢复正常。有时,如果我不重新启动应用程序,我可以刷新并且它会愉快地重新连接。
这就是为什么我认为这是“唤醒”问题。
代码大致轮廓:
我没有包含代码 - 我认为不需要。它有效(除了连接丢失)
需要注意的事项:只有一个“连接” - 我从不关闭它。我从来没有重新打开过。
我正在使用 Mongoose 、socketio。
/* constants */
var mongoConnect = 'myworkingconnectionstring-includingDBname';
/* includes */
/* settings */
/* Schema */
var db = mongoose.connect(mongoConnect);
/* Socketio */
io.configure(function (){
io.set('authorization', function (handshakeData, callback) {
});
});
io.sockets.on('connection', function (socket) {
});//sockets
io.sockets.on('disconnect', function(socket) {
console.log('socket disconnection')
});
/* The Routing */
app.post('/login', function(req, res){
});
app.get('/invited', function(req, res){
});
app.get('/', function(req, res){
});
app.get('/logout', function(req, res){
});
app.get('/error', function(req, res){
});
server.listen(port);
console.log('Listening on port '+port);
db.connection.on('error', function(err) {
console.log("DB connection Error: "+err);
});
db.connection.on('open', function() {
console.log("DB connected");
});
db.connection.on('close', function(str) {
console.log("DB disconnected: "+str);
});
我在这里尝试了各种配置,例如一直打开和关闭 - 但我相信,普遍的共识是像我一样打开一个包裹。 ??
我尝试过连接测试仪,它会不断检查连接的状态...即使这似乎表明一切正常 - 问题仍然会发生。
我从第一天起就遇到了这个问题。我一直使用 MongoLab 托管 MongoDB。 本地主机上的问题似乎更严重。但我在 Azure 和现在的 nodejit.su 上仍然存在问题。
这种事随处可见 - 一定是我、MongoDB 或 mongolab。
顺便说一句,我在 php 驱动程序方面也有过类似的经历。 (不过要确认这是在nodejs上)
如果能提供一些帮助,那就太好了 - 即使有人只是说“这是正常的”
提前致谢
抢
最佳答案
更新:我们对此主题的支持文章(本质上是本文的副本)已移至 our connection troubleshooting doc .
有一个已知问题,即 Azure IaaS 网络强制执行大约十三分钟的空闲超时(根据经验得出)。我们正在与 Azure 合作,看看是否不能让事情变得更加用户友好,但与此同时,其他人已经通过配置驱动程序选项来解决这个问题,取得了成功。
最大连接空闲时间
我们在与 Azure 和客户合作时发现的最有效的解决方法是将最大连接空闲时间设置为低于四分钟。这个想法是让驱动程序在防火墙强制解决问题之前回收空闲连接。例如,一位使用 C# 驱动程序的客户将 MongoDefaults.MaxConnectionIdleTime
设置为一分钟,这解决了他们的问题。
MongoDefaults.MaxConnectionIdleTime = TimeSpan.FromMinutes(1);
应用程序代码本身没有改变,但现在驱动程序在幕后积极回收空闲连接。结果也可以在服务器日志中看到:应用程序空闲期间有大量连接流失。
相关 mongo-user 线程 SocketException using C# driver on azure 中提供了有关此方法的更多详细信息。 .
保持事件
您还可以通过使用某种 keepalive 减少连接空闲来解决此问题。这实现起来有点棘手,除非你的驱动程序支持它开箱即用,通常是利用 TCP Keepalive 。如果您需要自己动手,请确保每隔几分钟从池中获取每个空闲连接,并发出一些简单且廉价的命令,可能是 ping .
处理断开连接
即使没有积极的防火墙设置,连接也会时不时地发生。在投入生产之前,您需要确保正确处理它们。
首先,请确保启用自动重新连接。如何执行此操作因驱动程序而异,但当驱动程序检测到由于连接不良而导致操作失败时,打开自动重新连接会告诉驱动程序尝试重新连接。
但这并不能完全解决问题。您仍然存在如何处理触发重新连接的失败操作的问题。自动重新连接不会自动重试失败的操作。这将是危险的,尤其是对于写入而言。因此通常会抛出异常并要求应用程序处理它。通常重试读取是理所当然的事情。但重试写入应该仔细考虑。
下面的 mongo shell session 演示了该问题。 mongo shell 默认启用自动重新连接。我在名为 stuff
的集合中插入一个文档,然后查找该集合中的所有文档。然后我设置了三十分钟的计时器并再次尝试相同的查找。它失败了,但是 shell 自动重新连接,当我立即重试时,发现它按预期工作。
% mongo ds012345.mongolab.com:12345/mydatabase -u *** -p ***
MongoDB shell version: 2.2.2
connecting to: ds012345.mongolab.com:12345/mydatabase
> db.stuff.insert({})
> db.stuff.find()
{ "_id" : ObjectId("50f9b77c27b2e67041fd2245") }
> db.stuff.find()
Fri Jan 18 13:29:28 Socket recv() errno:60 Operation timed out 192.168.1.111:12345
Fri Jan 18 13:29:28 SocketException: remote: 192.168.1.111:12345 error: 9001 socket exception [1] server [192.168.1.111:12345]
Fri Jan 18 13:29:28 DBClientCursor::init call() failed
Fri Jan 18 13:29:28 query failed : mydatabase.stuff {} to: ds012345.mongolab.com:12345
Error: error doing query: failed
Fri Jan 18 13:29:28 trying reconnect to ds012345.mongolab.com:12345
Fri Jan 18 13:29:28 reconnect ds012345.mongolab.com:12345 ok
> db.stuff.find()
{ "_id" : ObjectId("50f9b77c27b2e67041fd2245") }
我们随时为您提供帮助
当然,如果您有任何疑问,请随时联系我们[email protected] 。我们随时为您提供帮助。
https://stackoverflow.com/questions/13980236/
相关文章:
ruby-on-rails - 查询 Mongoid 哈希字段
javascript - 如何在 meteor 应用程序中向 mongodb 添加两列唯一 ID?
mongodb - 文档数据库 : Redundant data, 引用等(特别是 MongoDB)
node.js - 在 MongoDB 中删除时自动删除引用对象
mongodb - 寻找 1 x 100 万个交叉点的最佳解决方案? Redis、Mongo、其他
excel - NODE.JS: fatal error - JS 分配失败 - 进程内存不足,同时
mongodb - mongoengine - 忽略模式验证的额外字段