如何正确处理与node-postgres的意外断开/自动连接?

时间:2017-06-15 08:58:01

标签: 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相关)?

2 个答案:

答案 0 :(得分:0)

what we should do when this error is happening ? Does it mean that we have to reconnect the entire pool?

It means that simply having .on('error', cb) handler on the Pool object must be sufficient to automatically re-create the corresponding Client object, without requiring anything else from your side.

If you want a 100% reliable version of the driver, I suggest that you stick with version 5.1 for the moment. The newer versions did provide a few minor updates here and there, but the connectivity handling went a bit sideways with its new connection pool.

And although the most recent fixes do carry some hope that the known connectivity issues are gone, it is yet to be proven by time and proper tests.

See also some other thoughts I wrote about it previously. Some of the points there are still valid.

答案 1 :(得分:0)

我只是做了以下类似的事情:

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();

作为临时解决方案,这可以解决问题,但我注意到 startedAtcrashedAt 始终相隔 30 分钟。我敢肯定,某处有一个连接超时的配置变量。我还没有研究过,但以上应该足以回答您的问题。