Как правильно обрабатывать неожиданное отключение/автоматическое переподключение с помощью node-postgres?

После обновления с 5.1 до 6.2.4 я иногда (почти раз в день) вижу следующую ошибку, которая приводит к сбою нашего рабочего сервера:

Error: Connection terminated unexpectedly
2017-06-15T10:03:33.683+02:00 at Object.onceWrapper (events.js:293:19)
2017-06-15T10:03:33.683+02:00Connection terminated unexpectedly
2017-06-15T10:03:33.684+02:00 at Socket.<anonymous> (/home/bas/app_21386476-a451-424c-ad67-870442bbdbe7/node_modules/pg/lib/connection.js:138:10)
2017-06-15T10:03:33.684+02:00 at emitNone (events.js:86:13)
2017-06-15T10:03:33.684+02:00 at emitNone (events.js:91:20)
2017-06-15T10:03:33.684+02:00 at Connection.emit (events.js:188:7)
2017-06-15T10:03:33.684+02:00 at Socket.emit (events.js:188:7)
2017-06-15T10:03:33.685+02:00 at process._tickCallback (internal/process/next_tick.js:104:9)
2017-06-15T10:03:33.685+02:00undefined
2017-06-15T10:03:33.685+02:00 at _combinedTickCallback (internal/process/next_tick.js:80:11)
2017-06-15T10:03:33.685+02:00 at endReadableNT (_stream_readable.js:975:12)

Я видел https://github.com/brianc/node-postgres/pull/ 1316

AFAI, ошибка не выдавалась до этого патча, на данный момент у нас есть ошибка, выдаваемая в пуле.

Я немного запутался в том, что мы должны делать, когда происходит эта ошибка? Означает ли это, что мы должны переподключить весь пул? Но как ? Или это означает, что клиент, выдающий ошибку, окончательно мертв, поэтому мы скорее отбрасываем операцию, инициированную клиентом, и сообщаем пользователю, что его запрос отброшен. Но еще раз, как, поскольку обратный вызов client.query, похоже, не вызывается с этой ошибкой (возможно, как-то связан с https://github.com/brianc/node-postgres/issues/1322)?


person Arnaud Benhamdine    schedule 15.06.2017    source источник
comment
Разве мой ответ ниже не дает вам того, о чем вы спрашивали? Кроме того, если вы хотите избежать проблем с подключением, см. pg-promise, который может обрабатывать все такие проблемы автоматически.   -  person vitaly-t    schedule 17.06.2017


Ответы (2)


что мы должны делать, когда эта ошибка происходит? Означает ли это, что мы должны переподключить весь пул?

Это означает, что просто наличия обработчика .on('error', cb) для объекта Pool должно быть достаточно для автоматического повторного создания соответствующего объекта Client без каких-либо дополнительных требований с вашей стороны.

Если вам нужна на 100% надежная версия драйвера, я предлагаю вам на данный момент придерживаться версии 5.1. Более новые версии предоставили несколько незначительных обновлений здесь и там, но обработка подключения пошла немного боком с новым пулом подключений.

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

См. также некоторые другие мысли, которые я писал об этом ранее. Некоторые пункты там до сих пор в силе.

person vitaly-t    schedule 15.06.2017
comment
Все-таки версия 5.1 надежнее? - person pir; 27.06.2019
comment
@pir Нет, это не лучшая идея. Вместо этого вы должны использовать последнюю версию. - person vitaly-t; 27.06.2019

Я только что сделал что-то вроде следующего:

let client;

const connectDb = () => {
    const startedAt = new Date().getTime();

    client = new Client(dbConfig);

    client.on('error', (err) => {
        console.log('An error occurred with client => ', err);

        console.log('startedAt', startedAt);
        console.log('crashedAt', new Date().getTime());

        // Reconnect
        connectDb();
    });

    client.connect((err) => {
        if (err) {
            console.log(chalk.redBright(`[main] Connection error => ${err}`));
        } else {
            console.log(chalk.blueBright(`[main] Connected to db!`));
        }
    });
};

connectDb();

В качестве временного решения это сработало, но я заметил, что startedAt и crashedAt всегда отличались друг от друга на 30 минут. Я уверен, что где-то есть переменная конфигурации для тайм-аута соединения. Я еще не изучал это, но вышесказанное должно быть достаточным ответом на ваш вопрос.

person Mike K    schedule 25.05.2021