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一次,而之前的连接不能用了?


3 回复

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 连接。
  • 事件监听器:在 errorclose 事件中,我们不再直接调用 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()方法简化连接过程。
  • 监听errordisconnected事件来处理连接失败的情况,并在一定延迟后重新尝试连接。
  • 通过调整setTimeout的延迟时间,可以控制重试的频率,避免频繁重试导致的资源浪费。

这种处理方式可以提高应用在BAE平台上连接MongoDB的稳定性。如果问题依然存在,建议检查BAE平台的具体限制和配置,可能需要进一步调整连接参数或优化应用逻辑。

回到顶部