Предотвращение множественных подключений MongoDB в NodeJS - PullRequest
0 голосов
/ 24 августа 2018

Я видел несколько сообщений на эту тему;одна из которых помогла мне прогрессировать, но у меня все еще есть проблема.

Моя база данных Mongo переполнена соединениями и выдает ошибки.У меня есть несколько разных соединений, которые я устанавливаю, используя имя клиента.В сети я нашел этот полезный класс:

export default class ConnectionManager {
static databases: any = {};

static getConnection(customer: string) : Promise<typeof mongoose> {
    if (this.databases[customer]) return Promise.resolve(this.databases[customer]);

    return new Promise<typeof mongoose>((resolve: any, reject: any) => {
        mongoose.connect(process.env.MONGOOSE_BASE_SERVER_URL + customer, { useNewUrlParser: true })
            .then((newDb: mongoose.Mongoose) => { 
                this.databases[customer] = newDb;
                resolve(this.databases[customer]);
            });
    });
  }
}

Как я уже говорил, это помогает - он работает, если соединение уже существует.

Проблема в том, что у меня запланированное задание, которое может быть немедленноЗалить API запросами после истечения времени ожидания существующих соединений.Если API на данный момент заполнен запросами - они приходят слишком быстро, и это открывает сотни соединений, и я все еще сталкиваюсь с той же проблемой;до того, как ConnectionManager.database мог обновиться новым соединением.

Изо всех сил пытался придумать, как этого избежать.Кто-нибудь есть какой-нибудь совет?

Спасибо,

РЕДАКТИРОВАТЬ - думаю, это в основном происходит после перезапуска службы.Вот пример ошибки:

{ Error: read ECONNRESET
    at TCP.onread (net.js:660:25)
  name: 'MongoNetworkError',
  errorLabels: [ 'TransientTransactionError' ],
  [Symbol(mongoErrorContextSymbol)]: {} }
{ MongoNetworkError: connection 202 to localhost:27017 closed
    at Socket.<anonymous> (.../node_modules/mongodb-core/lib/connection/connection.js:275:9)
    at Object.onceWrapper (events.js:273:13)
    at Socket.emit (events.js:182:13)
    at TCP._handle.close (net.js:599:12)
  name: 'MongoNetworkError',
  errorLabels: [ 'TransientTransactionError' ],
  [Symbol(mongoErrorContextSymbol)]: {} }

1 Ответ

0 голосов
/ 24 августа 2018

Обещания, естественно, обеспечивают поведение кэширования, потому что разрешенное обещание дает тот же результат, когда оно объединено в цепочку.

Надлежащий подход заключается в том, чтобы хранить обещания в databases, таким образом, не будет условий гонки, которые приводят кнесколько соединений с одинаковым именем, то есть databases[customer] = Promise.resolve(mongoose.connect(...)).

Но это не нужно для Mongoose, которая внутренне связывает обещания соединения;объект подключения может быть просто сохранен и использован.Несколько соединений создаются методом createConnection.

Кроме того, статические классы являются антипаттернами.Это может быть объект или просто функция:

export const _databases = {};

export const getConnection = (customer) => {
  if (!_databases[customer])
    _databases[customer] = mongoose.createConnection(
      process.env.MONGOOSE_BASE_SERVER_URL + customer,
      { useNewUrlParser: true }
    );

  return _databases[customer];
}

Нет очевидной причины для публичного экспорта объекта databases.Его можно экспортировать для тестирования.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...