javascript - 节点 Postgres Pub/Sub - 保留剩余的连接槽

标签 javascript postgresql socket.io node-postgres

我用 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 我会看到:

enter image description here

我认为使用 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/

相关文章:

javascript - jQuery 的 jsfiddle 示例不适用于 jQuery 代码

javascript - 在 IE7/8 中将 excanvas 元素保存为图像

regex - regexp_replace 上的函数导致 Postgres

javascript - Express JWT 错误 : Not enough or too many segments in socket. io 初始身份验证

android - 将 Socket Io 服务器与 Android App 集成

node.js - Websocket 无法在 Google App Engine 上运行

javascript - 如果不存在则创建子对象

javascript - javascript垃圾收集器不收集setTimeout()?

postgresql - ST_DWithin 耗时较长(超过6000ms)

linux - Linux 上的 PostgreSQL 数据库默认位置