Nodejs BAE上mongoose长连接问题(新!),求可怜,进来看一眼呗
Nodejs BAE上mongoose长连接问题(新!),求可怜,进来看一眼呗
##这个貌似是新问题! 之前出现长连接问题看一个帖子(地址)搞定了,最近突然发现又报错了~~~~我的连接代码如下:
var mongoose = require('mongoose'),
settings = require('./settings.js'),
db = mongoose.createConnection(); // connect to mongoDB with mongoose
//open connection to mongoDB with db options
db.open(settings.host, settings.db, settings.port, settings.options, functio n() {
console.log('mongoDB connected!');
console.log('host: ' +settings.host + ' db: ' + settings.db + ' port:' +
settings.port );
});
db.on('error', function (err) {
console.error.bind(console, 'connection error:');
//listen BAE mongodb,if except throws then close the connection
//why have to do this?Clause it'll be disconnected if it free after 30s by BAE
console.log("db on error!"); //!!跟踪错误的日志
db.close();
});
//when close, reopen a connect
db.on('close', function() {
console.log("db on close!"); //!!跟踪错误的日志
db.open(settings.host, settings.db, settings.port, settings.options, funct ion() {
console.log("db reopen!"); //!!跟踪错误的日志
});
});
module.exports = {
db: db,
mongoose: mongoose
}
在BAE后台查看日志,发现30s后我加的跟踪错误的日志都会打出来,也就是说当连接关闭之后再重新打开这个连接的代码是执行了的,还是报no open connections的错误,是不是需要每次都重新createConnection一次,而之前的连接不能用了?
Nodejs BAE上mongoose长连接问题(新!),求可怜,进来看一眼呗
问题描述
之前解决过 Mongoose 在百度应用引擎(BAE)上的长连接问题,但最近再次遇到这个问题。每次连接关闭后尝试重新连接时,仍然会报 no open connections
的错误。
当前的连接代码
var mongoose = require('mongoose');
var settings = require('./settings.js');
// 创建 Mongoose 连接
var db = mongoose.createConnection();
// 打开 MongoDB 连接
db.open(settings.host, settings.db, settings.port, settings.options, function() {
console.log('MongoDB connected!');
console.log('Host: ' + settings.host + ', DB: ' + settings.db + ', Port: ' + settings.port);
});
// 错误处理
db.on('error', function (err) {
console.error('Connection error:', err);
console.log("db on error!");
db.close();
});
// 关闭处理
db.on('close', function() {
console.log("db on close!");
db.open(settings.host, settings.db, settings.port, settings.options, function() {
console.log("db reopened!");
});
});
module.exports = {
db: db,
mongoose: mongoose
};
问题分析
在 BAE 后台查看日志时,发现连接关闭后的重连代码被触发,但是仍然报 no open connections
的错误。这可能是因为之前的连接对象已经失效,需要重新创建一个新的连接对象。
解决方案
根据上述分析,我们需要在连接关闭时重新创建一个新的连接对象,而不是简单地调用 db.open()
方法。
修改后的代码
var mongoose = require('mongoose');
var settings = require('./settings.js');
function createMongooseConnection() {
var db = mongoose.createConnection();
db.on('error', function (err) {
console.error('Connection error:', err);
console.log("db on error!");
db.close();
});
db.on('close', function() {
console.log("db on close!");
createMongooseConnection();
});
return db;
}
var db = createMongooseConnection();
db.once('open', function() {
console.log('MongoDB connected!');
console.log('Host: ' + settings.host + ', DB: ' + settings.db + ', Port: ' + settings.port);
});
module.exports = {
db: db,
mongoose: mongoose
};
解释
createMongooseConnection
函数:该函数负责创建并返回一个新的 Mongoose 连接。- 事件监听器:在
error
和close
事件中,我们不再直接调用db.open()
,而是调用createMongooseConnection()
来重新创建一个新的连接。 db.once('open')
:确保只有在连接成功后才打印连接成功的消息。
通过这种方式,可以确保每次连接失败或关闭时都能正确地重新创建一个新的连接,从而避免 no open connections
的错误。
刚又看了后台日志,
db reopen!
db on close!
db on error!
db reopen!
db on close!
db on error!
db reopen!
db on close! 都是打出来的,一直刷,为啥就是打不开这个连接呢?
在BAE(百度应用引擎)上使用Mongoose时遇到长连接问题,可能是由于BAE平台本身对连接的限制导致的。BAE会自动关闭空闲30秒以上的连接,这可能导致你的应用在重新打开连接时仍然遇到“no open connections”的错误。
你可以尝试优化你的连接管理逻辑,确保每次连接失败时都能正确地重新建立连接。以下是一个改进后的示例代码:
var mongoose = require('mongoose');
var settings = require('./settings.js');
mongoose.connect(`mongodb://${settings.host}:${settings.port}/${settings.db}`, settings.options, (err) => {
if (err) {
console.error('MongoDB connection error:', err);
} else {
console.log('MongoDB connected!');
}
});
mongoose.connection.on('error', (err) => {
console.error('MongoDB connection error:', err);
setTimeout(() => {
mongoose.connect(`mongodb://${settings.host}:${settings.port}/${settings.db}`, settings.options);
}, 5000); // 重试间隔时间可以根据实际情况调整
});
mongoose.connection.on('disconnected', () => {
console.log('MongoDB disconnected, attempting to reconnect...');
setTimeout(() => {
mongoose.connect(`mongodb://${settings.host}:${settings.port}/${settings.db}`, settings.options);
}, 5000); // 重试间隔时间可以根据实际情况调整
});
module.exports = {
mongoose: mongoose
};
在这个改进后的代码中:
- 使用
mongoose.connect()
方法简化连接过程。 - 监听
error
和disconnected
事件来处理连接失败的情况,并在一定延迟后重新尝试连接。 - 通过调整
setTimeout
的延迟时间,可以控制重试的频率,避免频繁重试导致的资源浪费。
这种处理方式可以提高应用在BAE平台上连接MongoDB的稳定性。如果问题依然存在,建议检查BAE平台的具体限制和配置,可能需要进一步调整连接参数或优化应用逻辑。