【发布时间】:2016-03-02 06:19:21
【问题描述】:
问题是 Mongoose 在以下情况下失去连接:
- Node App 已启动,一切正常(可访问数据库等)
- 本地运行的 Mongo 服务器进程(2.6.10 版)停止,然后在 15 秒后启动,一切正常(可访问数据库等)
- Mongo 进程已停止。
- 向 Express 发出请求,尝试访问 DB(使用 Mongoose) - 无法按预期访问。
- Mongo 进程已启动。
- 发出了相同的请求,即使 Mongo 已启动,也无法访问 DB。
如果我重新启动 Node JS 应用程序,一切正常。
为什么对 Mongo 的失败查询(使用 Mongoose 版本 4.4.5)会在 DB 进程再次启动时阻止连接恢复?
我们是否应该实施重试机制来尝试恢复连接,直到 DB 变得可访问?
我已经尝试过here提到的配置,但没有成功。
任何帮助将不胜感激。
下面是我们的连接助手的示例代码:
'use strict';
const _ = require('lodash');
const mongoose = require('mongoose');
const config = require('../config');
const logger = require('../logger');
const _instance = Symbol('instance');
const _enforcer = Symbol('enforcer');
const _members = Symbol('members');
/**
* Singleton implementation of ConnectionHelper module
* This module is responsible to reusing common db connections in the application
* @type {ConnectionsHelper}
*/
module.exports = class ConnectionsHelper {
constructor(enforcer) {
if (enforcer !== _enforcer) {
throw new Error('invalid singleton instantiation');
}
initConnectionFromConfig.call(this);
}
/**
* The single instance
* @returns {*}
*/
static get instance() {
if (!this[_instance]) {
this[_instance] = new ConnectionsHelper(_enforcer);
}
return this[_instance];
}
/**
* method retrieves connection by its name
* @param connectionKey
* @returns {*}
*/
getConnection(connectionKey) {
return this[_members][connectionKey];
}
/**
* method disconnects all underlying connections
* @returns {void|MongooseThenable}
*/
closeConnections() {
return mongoose.disconnect();
}
};
function initConnectionFromConfig() {
this[_members] = {};
const dbsConnections = config.get('dbsConnections');
_.forEach(dbsConnections, (connection, connectionName) => {
const protocol = connection.protocol;
const repSetPath = connection.mongoPath.join(',');
const options = connection.options;
options.server = {auto_reconnect: true, socketOptions: {keepAlive: 1, connectTimeoutMS: 30000 }};
options.replset = {socketOptions: {keepAlive: 1, connectTimeoutMS: 30000 }};
this[_members][connectionName] = mongoose.createConnection(protocol + repSetPath, options);
addConnectionEvents.call(this, connectionName);
});
}
function initConnectionIfNeeded() {
this[_members] = {};
const dbsConnections = config.get('dbsConnections');
_.forEach(dbsConnections, (connection, connectionName) => {
const protocol = connection.protocol;
const repSetPath = connection.mongoPath.join(',');
const options = connection.options;
//options.server = {auto_reconnect: true, socketOptions: {keepAlive: 1, connectTimeoutMS: 30000 }};
//options.replset = {socketOptions: {keepAlive: 1, connectTimeoutMS: 30000 }};
this[_members][connectionName] = mongoose.createConnection(protocol + repSetPath, options);
addConnectionEvents.call(this, connectionName);
});
}
function addConnectionEvents(connectionName) {
const connection = this[_members][connectionName];
connection.on('connected', () => {
logger.debug(`Mongoose connection open`);
});
connection.on('error', (err) => {
logger.debug(`Mongoose connection error: ${err}`);
});
connection.on('exception', (err) => {
logger.debug(`Mongoose connection exception: ${err}`);
});
connection.on('disconnected', () => {
logger.debug(`Mongoose connection disconnected`);
});
connection.on('reconnected', () => {
logger.debug(`Mongoose connection reconnected`);
});
connection.on('open', () => {
logger.debug(`Mongoose connection is open`);
});
// If the Node process ends, close the Mongoose connection
process.on('SIGINT', () => {
connection.close(() => {
logger.debug(`Mongoose default connection disconnected through app termination`);
process.exit(0);
});
});
}
【问题讨论】:
-
您能告诉我们您的 mongodb 连接代码吗?
-
options.server = {auto_reconnect: true, socketOptions: {keepAlive: 1, connectTimeoutMS: 30000 }}; options.replset = {socketOptions: {keepAlive: 1, connectTimeoutMS: 30000 }}; this[_members][connectionName] = mongoose.createConnection(protocol + repSetPath, options); -
你能给我们更多的代码吗?
this在哪里使用?在一个模块中?你是从这个模块导出的吗?顺便说一句,您可以直接将代码添加到您的问题中......
标签: node.js mongodb express mongoose