我用 node-postgres 和 socket.io 构建了一个通知系统。系统工作正常,但是,我在启动时遇到错误。
remaining connection slots are reserved for non-replication superuser connections
我怀疑这是因为没有将客户端释放回池中。
Pool.connect()
.then(client => {
return client.query('LISTEN "new_notification"')
.then(result => {
client.on('notification', data => {
// Handle the notification
});
// Should release here
})
.catch(e => {
// Should release here
this.log(e.message, 'error');
});
})
.catch(e => {
this.log(e.message, 'error')
});
然而,即使在标记了 //Should release here
的位置添加了 client.release()
之后,我仍然会收到错误消息。不过,通知仍然有效。
当服务器启动时,它会创建一个 HeyListen
对象,上面的 Pool
也会在其中创建。
现在,上述错误通常发生在服务器启动并充满连接时。有 6 个站点处理与用户的连接。每个用户都会生成一个到 socket.io 服务器的新连接,当通过 socket.io 触发 disconnecting
事件时,他们将从已连接用户列表中删除。每次用户连接时,如果他们有未完成的通知,他们就会触发对 postgres 的查询。这是查询对象:
const conn = this.getConnectionType(pool);
conn.connect()
.then(client => {
return client.query(query_string, params)
.then(result => {
client.release();
callback(null, result);
})
.catch(error => {
client.release();
callback(error, null);
});
})
.catch(error => {
callback(error, null);
});
如果我在我的 psql 服务器上运行 Select * From pg_stat_activity
我会看到:
我认为使用 client.release()
应该删除这些连接?重新运行上面的查询显示不同的查询结果,因此一些被删除。这是没有足够的 max_connections
可用的问题吗?如果是这样,为我的用例增加这个数字是个好主意吗?
最佳答案
在为 Node.js 和 PostgreSQL 试验我自己的 pub/sub 客户端功能时,我在用完可用连接时看到了该错误。如果我没记错的话,你遇到的问题是使用 node-postgres
包,与 LISTEN
一起使用的连接被认为是事件的并且正在使用中底层连接池,直到客户端使用 UNLISTEN
停止监听。
但是,如果您停止监听给定的连接,您将不会再收到那些有用的通知
事件。有点进退两难。
如果可能,我建议您考虑设置较少数量的专用连接,专门用于在您的六个应用程序中通过 PostgreSQL 收听各种 channel ,然后使用单独的连接来执行您的其他查询。我不知道这对您当前的流量负载有多可行或性能如何,但理论上它应该会降低使用池中所有可用连接的可能性。
出于好奇,您让每个用户的连接LISTEN
单独接收通知的理由是什么?有可能 pass a payload to listeners通过 NOTIFY
,所以如果您有某种方法来识别单个用户,您可以向您的六个应用程序发送一个负载,声明通知是针对哪个用户的,并且您的六个应用程序中的每一个都可以将该信息转发给正确的用户连接。
关于javascript - 节点 Postgres Pub/Sub - 保留剩余的连接槽,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53784672/