node.js - Mongoose 在未指定的时间段后停止响应

自从我开始开发我的项目(12 个月前!)以来,我一直在为这个问题绞尽脑汁,总是假设我会在准备发布之前找到答案......不幸的是,这不是案例!

基本上,我有一个在 Azure 上运行的相当简单的 Node.js 服务器,使用 mongoose 连接到 MongoLab(现在是 MLab)数据库。

连接代码如下所示:

// Connect to DB
//mongoose.set('debug', true);
mongoose.connect(envConfig.app.db, {
    server: {
        auto_reconnect: true,
        socketOptions: {
            keepAlive: 1,
            connectTimeoutMS: 30000,
            socketTimeoutMS : 30000,
        }
    },
    replset: {
        auto_reconnect: true,
        socketOptions: {
            keepAlive: 1,
            connectTimeoutMS: 30000,
            socketTimeoutMS : 30000,
        }
    }
}, function (err) {
    if (err) winstonLogger.error(err);
});
mongoose.connection.on('connecting', function () {
    console.log('Connecting to MongoDB...');
});
mongoose.connection.on('connected', function () {
    console.log('MongoDB connected!');
});
mongoose.connection.on('open', function () {
    console.log('MongoDB connection opened!');
});
mongoose.connection.on('error', function (err) {
    console.error('Error in MongoDb connection: ' + err.stack);
    winstonLogger.error(err);
    mongoose.disconnect();
});
mongoose.connection.on('disconnected', function () {
    winstonLogger.error('MongoDB disconnected!');
    mongoose.connect(envConfig.app.db, {
        server: {
            auto_reconnect: true,
            socketOptions: {
                keepAlive: 1,
                connectTimeoutMS: 30000,
                socketTimeoutMS : 30000,
            }
        },
        replset: {
            auto_reconnect: true,
            socketOptions: {
                keepAlive: 1,
                connectTimeoutMS: 30000,
                socketTimeoutMS : 30000,
            }
        }
    });
});
mongoose.connection.on('reconnected', function () {
    console.log('MongoDB reconnected!');
});
mongoose.connection.on('close', function () {
    console.log('MongoDB closed');
});

您看到的所有额外超时选项等都是我尝试解决此问题的一部分(无济于事)。

这是一个典型的请求:

AccessToken.findOne({ token: token })
            .maxTime(10000)
            .exec(function (err, accessToken) {
                // If I even got to here I would be happy
                if (err) return done(err);
                // If I could consistently get to here, my project would be finished and I would enjoy being alive again
            });

所以,当我启动服务器时,一切都运行良好。而且它一直工作得很好......有时是几天,有时是几个小时,有时是几分钟。然而,在某些时候,请求会命中此代码,并且它会......挂起。没有超时,没有错误。没什么。我没有在任何日志中找到任何证据来显示正在发生的事情。我的快速记录器最终放弃了,我得到了类似的信息:

POST /api/auth/verify - - ms - -

因此,此时,我唯一的选择是重新启动服务器,因为我无法完成数据库请求(或超时,或显示错误),无论是出于爱还是金钱。

我在互联网上搜索了一年,希望找到解决方案,但我尝试过的所有方法都导致......没有任何结果......相同的结果。我什至尝试在 Azure 上运行我自己的副本集,而不是使用 MongoLab。同样的问题。我唯一的想法是,这是一个 Azure 问题,没有明显的解决方案,但我真的不热衷于寻找另一台主机。话虽这么说,我不明白为什么 Mongoose 请求不会超时或显示任何错误,即使我设置了 maxTime...

以下是 MongoLab 提供的一些关于我认为可能存在问题的信息: http://docs.mlab.com/connecting/#known-issues , 但正如你所看到的,我已经尝试了他们建议的一切,甚至更多,但没有成功。

我真的很不知所措,整个情况同时令人大脑 NumPy 、心碎和令人难以置信的愤怒。

如果有人有任何想法,我会永远爱你......

提前谢谢您!

-卢克

最佳答案

好的,我已经有一段时间没有遇到这个问题了。我对连接设置做了很多小的更改,但我认为影响最大的是显式设置 ha(高可用性)和 haInterval replset 选项,或者可能将连接代码移动到我的 app.js 的最末尾.

最终的连接代码如下:

// Connect to DB
var connectionOptions = {
    replset: {
        socketOptions: {
            connectTimeoutMS: 300000, // 5 minutes
            keepAlive: 120
        },
        ha: true, // Make sure the high availability checks are on
        haInterval: 10000, // Run every 10 seconds
    }
};
//mongoose.set('debug', true);
mongoose.connect(envConfig.app.db, connectionOptions, function (err) {
    if (err) winstonLogger.error(err);
});
mongoose.connection.on('connecting', function () {
    console.log('Connecting to MongoDB...');
});
mongoose.connection.on('connected', function () {
    console.log('MongoDB connected!');
});
mongoose.connection.on('open', function () {
    console.log('MongoDB connection opened!');
});
mongoose.connection.on('error', function (err) {
    winstonLogger.error(err);
    mongoose.disconnect();
});
mongoose.connection.on('disconnected', function () {
    winstonLogger.error('MongoDB disconnected!');
    mongoose.connect(envConfig.app.db, connectionOptions, function (err) {
        if (err) winstonLogger.error(err);
    });
});
mongoose.connection.on('reconnected', function () {
    console.log('MongoDB reconnected!');
});
mongoose.connection.on('close', function () {
    winstonLogger.error('MongoDB closed');
});
if (mongoose.connection.db.serverConfig.s.replset) {
    mongoose.connection.db.serverConfig.s.replset.on('ha', function(type, data) {
        console.log('replset ha ' + type);
    });
    mongoose.connection.db.serverConfig.s.replset.on('timeout', function () {
        winstonLogger.error('MongoDB timeout');
    });
}

我还打开了 Azure WebApp 的 AlwaysOn 选项(这似乎没有太大效果,但现在它正在工作,我不会将其关闭!)。

这个问题似乎确实与故障转移后未重新连接有关,但我不能 100% 肯定地说。

希望这能帮助遇到同样问题的其他人...希望我没有操之过急,只是让它在几天内再次停止工作(如果发生这种情况,我会回来的!) .

感谢所有提供建议的人,我永远感激不已:)

https://stackoverflow.com/questions/35951957/

相关文章:

node.js - 我的 Electron 应用程序启动时如何启动 mongodb 服务

json - 如何使用 Pentaho 从 json 中的三个表到 mongodb 执行复杂文档

node.js - 如何使用 mongo/mongoose 连接远程数据库

mongodb - 为启用身份验证的 mongodb 运行 mongostat 时出现问题

mongodb - 使用 mongoose 正则表达式与文本在 mongodb 中搜索

mongodb - 如何从 mongodb 集合中删除空字符串?

java - 使用 java 和 video.js 从输入流加载视频

node.js - docker compose = ECONNREFUSED 中的 NodeJS

node.js - 错误 : Cannot find module './drivers' with

node.js - Nodejs 我需要使用 Passport