再次访问数据库时,不会恢复Mongoose连接

时间:2016-03-02 06:19:21

标签: node.js mongodb express mongoose

问题是Mongoose在以下情况下失去了连接:

  1. 节点应用已启动,一切似乎都很好(可访问数据库等)
  2. 本地运行的Mongo服务器进程(版本2.6.10)已停止,然后在15秒后启动,一切似乎都很好(可访问数据库等)
  3. Mongo进程已停止。
  4. 发出快递请求,尝试转到数据库(使用Mongoose) - 无法按预期访问。
  5. Mongo进程已启动。
  6. 提出同样的请求,即使Mongo已启动,也无法访问数据库。
  7. 如果我重新启动Node JS应用程序,一切正常。

    为什么Mongo的查询失败(使用Mongoose版本4.4.5)会阻止在数据库进程再次启动时恢复连接?

    我们是否应该实施重试机制来尝试恢复连接,直到可以访问DB?

    我已经尝试了here提到的配置,但它没有用。

    任何帮助都将不胜感激。

    Bellow是我们的连接助手的示例代码:

    '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);
        });
      });
    }
    

1 个答案:

答案 0 :(得分:1)

我遇到了同样的问题。我做的是在这里重启mongoose:

mongoose.connection.on('disconnected', function () {  
  console.log('Mongoose default connection disconnected'); 
  console.log("Trying to reconnect");

  function connect(){
    mongoose.connect(dbPath, function(err){
      if(err) console.log("Error while trying to reconnect to MongoDB");
    });
  }
  setTimeout(connect, 3000);
});

我还使用setTimeout()使其每3秒尝试一次。

function FormSubmission(formId) {
    $.ajax({
        type: "POST",
        data: $("#" + formId).serialize(),
        url: $("#" + formId).attr("action"),
        success: function(data) {
            // in case of success you redirect the client
            window.location = data.the_url;
        },
        error: function () {
            // show error
        },
    }).done(function (response) {
        // show error or something else
    });
}

我也使用ForeverJS。