rob*_*mes 26 azure mongoose mongodb node.js mlab
我正在使用nodejs和mongoDB - 我遇到了一些连接问题.
好吧,实际上是"唤醒"问题!它连接得非常好 - 速度非常快,我对结果非常满意.
我的问题:如果我暂时不使用连接(我说同时,因为时间范围变化5分钟以上)似乎停滞不前.我没有解决断线事件 - 它只是挂起.
最终我收到像Error这样的回复:无法连接到[*.mongolab.com:*] - (*=屏蔽值)
快速重启应用程序,连接再次很棒.有时,如果我不重新启动应用程序,我可以刷新并重新连接愉快.
这就是我认为这是"唤醒"问题的原因.
粗略的代码轮廓:
我没有包含代码 - 我认为不需要.它的工作原理(除了连接丢失)
注意事项:只有一个"连接" - 我永远不会关闭它.我从未重开过.
我正在使用猫鼬,袜子.
/* 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);
});
Run Code Online (Sandbox Code Playgroud)
我在这里尝试过各种各样的配置,比如一直打开和关闭 - 我相信,尽管如此,普遍的共识是要像我在一个公开的包装那样做.??
我已经尝试了一个连接测试器,它不断检查连接的状态......即使这似乎说是一切正常 - 问题仍然存在.
从第一天起我就遇到过这个问题.我一直用MongoLab托管MongoDB.localhost上的问题似乎更糟.但我仍然在Azure和现在nodejit.su上有问题.
它随处可见 - 它必须是我,MongoDB或mongolab.
顺便说一下,我也有过与php驱动程序相似的经历.(虽然确认这是在nodejs上)
一些帮助会很棒 - 即使有人只是说"这是正常的"
提前致谢
抢
jar*_*red 28
更新:我们针对此主题的支持文章(基本上是此帖的副本)已移至我们的连接故障排除文档.
Azure IaaS网络强制执行大约十三分钟的空闲超时(根据经验得出)存在一个已知问题.我们正在与Azure合作,看看我们是否能够使用户更友好,但与此同时,其他人通过配置驱动程序选项来解决问题也取得了成功.
最大连接空闲时间
我们在与Azure和我们的客户合作时发现的最有效的解决方法是将最大连接空闲时间设置为低于四分钟.这个想法是在防火墙强制解决问题之前让驱动程序回收空闲连接.例如,一个使用C#驱动程序的客户设置MongoDefaults.MaxConnectionIdleTime
为一分钟,它就清理了问题.
MongoDefaults.MaxConnectionIdleTime = TimeSpan.FromMinutes(1);
Run Code Online (Sandbox Code Playgroud)
应用程序代码本身没有改变,但现在在幕后,驱动程序积极地回收空闲连接.结果也可以在服务器日志中看到:在应用程序的空闲时段内有大量连接流失.
在相关的mongo-user线程中有更多关于此方法的详细信息,在Azure上使用C#驱动程序进行SocketException.
活着
您还可以通过某种keepalive使您的连接闲置,从而解决此问题.实施起来有点棘手,除非你的驱动程序支持开箱即用,通常是利用TCP Keepalive.如果你需要自己动手,请确保每隔几分钟从池中获取每个空闲连接并发出一些简单而便宜的命令,可能是ping.
处理断开连接
即使没有积极的防火墙设置,也可能不时发生断开连接.在您投入生产之前,您需要确保正确处理它们.
首先,请务必启用自动重新连接.如何执行此操作因驱动程序而异,但当驱动程序检测到操作失败,因为连接错误时,自动重新连接会导致驱动程序尝试重新连接.
但这并不能完全解决问题.您仍然遇到如何处理触发重新连接的失败操作的问题.自动重新连接不会自动重试失败的操作.这将是危险的,特别是对于写作.因此通常会抛出异常并要求应用程序处理它.通常重试读取是很容易的.但是应该仔细考虑重试写入.
下面的mongo shell会话演示了这个问题.默认情况下,mongo shell启用了自动重新连接.我在一个名为的集合中插入一个文档,stuff
然后查找该集合中的所有文档.然后我设置了一个30分钟的计时器并再次尝试相同的查找.它失败了,但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") }
Run Code Online (Sandbox Code Playgroud)
我们在这里提供帮助
当然,如果您有任何疑问,请随时通过support@mongolab.com与我们联系.我们在这里提供帮助.
rob*_*mes 18
感谢所有帮助人员 - 我已设法在localhost上解决此问题并部署到实时服务器.
这是我现在正在使用的连接代码:
var MONGO = {
username: "username",
password: "pa55W0rd!",
server: '******.mongolab.com',
port: '*****',
db: 'dbname',
connectionString: function(){
return 'mongodb://'+this.username+':'+this.password+'@'+this.server+':'+this.port+'/'+this.db;
},
options: {
server:{
auto_reconnect: true,
socketOptions:{
connectTimeoutMS:3600000,
keepAlive:3600000,
socketTimeoutMS:3600000
}
}
}
};
var db = mongoose.createConnection(MONGO.connectionString(), MONGO.options);
db.on('error', function(err) {
console.log("DB connection Error: "+err);
});
db.on('open', function() {
console.log("DB connected");
});
db.on('close', function(str) {
console.log("DB disconnected: "+str);
});
Run Code Online (Sandbox Code Playgroud)
我认为最大的变化是使用"createConnection"而不是"connect" - 我之前使用过这个,但也许这些选项现在有所帮助.这篇文章帮助了很多http://journal.michaelahlers.org/2012/12/building-with-nodejs-persistence.html
如果我老实说我不太确定为什么我添加了这些选项 - 正如@jareed所提到的,我也发现有些人成功使用"MaxConnectionIdleTime" - 但据我所知,javascript驱动程序没有有这个选项:这是我试图复制行为的尝试.
到目前为止一直很好 - 希望这有助于某人.
更新:2013年4月18日 注意,这是第二个具有不同设置的应用程序
现在我以为我已经解决了这个问题,但问题是最近在另一个应用程序上又出现了问题- 使用相同的连接代码.困惑!!!
然而,设置略有不同......
这个新应用程序使用IISNode在Windows机器上运行. 我最初并没有认为这很重要.
我读过Azure上的mongo可能存在一些问题(@jareed),所以我把数据库移到了AWS - 问题仍然存在.
所以我再次开始使用该选项对象,阅读相当多的内容.得出这个结论:
options: {
server:{
auto_reconnect: true,
poolSize: 10,
socketOptions:{
keepAlive: 1
}
},
db: {
numberOfRetries: 10,
retryMiliSeconds: 1000
}
}
Run Code Online (Sandbox Code Playgroud)
这是我的原始选项对象我更有教育意义.然而 - 它仍然没有好处.
现在,出于某种原因,我不得不离开那个窗口框(与未编译的模块有关) - 移动比花费一周试图让它工作更容易.
所以我将我的应用程序移动到nodejitsu.低,看到我的联系还活着!呜!
所以….这是什么意思......我不知道!我所知道的是这些选项似乎适用于Nodejitsu .... 为了我.
我相信IISNode使用某种"永远"的脚本来保持应用程序的活力.现在公平地说,应用程序不会因此而崩溃,但我认为必须有某种"应用程序周期"不断刷新 - 这就是它如何进行持续部署(ftp代码,不需要重启app) - 也许这是一个因素; 但我现在只是猜测.
当然这一切都意味着现在,这是不是解决了.它仍然没有解决.它在我的设置中为我解决了.
针对仍有此问题的人提出的一些建议:
确保您使用node.js的最新mongodb客户端.从v1.2.x迁移到v1.3.10(截至今天的最新版本)时,我注意到该领域的重大改进
您可以将选项对象传递给MongoClient.connect.从Azure连接到MongoLab时,以下选项适用于我:
options = {db:{},server:{auto_reconnect:true,socketOptions:{keepAlive:1}},replSet:{},mongos:{}};
MongoClient.connect(dbUrl,options,function(err,dbConn){// your code});
请参阅另一个答案,其中我描述了如何处理似乎更可靠的'close'事件./sf/answers/1448300591/