重用Redis连接:套接字意外关闭-node-redis

问题描述 投票:0回答:4

首先,让我告诉你我如何在 NodeJS 应用程序中使用 Redis 连接:

  • 我使用单例类在整个应用程序中重复使用一个连接。
class RDB {

    static async getClient() {
        if (this.client) {
            return this.client
        }

        let startTime = Date.now();

        this.client = createClient({
            url: config.redis.uri
        });

        await this.client.connect();

        return this.client;
    }

}

出于某种原因 - 我不知道 - 我的应用程序有时会崩溃,无缘无故地出现错误 - 这种情况大约每周发生一两次:

Error: Socket closed unexpectedly

现在,我的问题:

  1. 这样使用Redis连接可以吗?我的做法有问题吗?
  2. 为什么会出现这种情况?为什么我的套接字意外关闭?
  3. 有没有办法捕获此错误(使用我的方法)或实现 Redis 连接的任何其他良好实践?
node.js sockets redis node-redis
4个回答
9
投票

我使用“错误”监听器解决了这个问题。只需聆听即可 - 避免节点应用程序崩溃。

client.on("error", function(error) {
   console.error(error);
   // I report it onto a logging service like Sentry. 
});

6
投票

我也遇到过类似的套接字意外关闭问题。当我将 node-redis 从 3.x 升级到 4.x 时,问题开始出现。当我将 redis-server 从 5.x 升级到 6.x 后,问题就消失了。


3
投票

您应该声明 RDB 类的私有静态成员“client”,如下所示:

private static client;

在静态方法中,你不能引用'this'的实例,你需要像这样引用静态类成员:

RDB.client

最好检查客户端的连接是否打开,而不是简单地检查客户端是否存在(考虑到您正在使用“redis”npm 库)。像这样:

if (RDB.client && RDB.client.isOpen)

更改后,您的代码应如下所示:

class RDB {
    private static client;

    static async getClient() {
        if (RDB.client && RDB.client.isOpen) {
            return RDB.client;
        }

        RDB.client = createClient({
            url: config.redis.uri
        });

        await RDB.client.connect();

        return RDB.client;
    }
}

注意:connect()方法和isOpen属性仅存在于redis版本^4.0.0中。


0
投票

我遇到了同样的问题(套接字意外关闭),但仅限于远程 Redis 服务器,所以我发现 TLS 可能存在问题。所以我尝试使用

redis://
而不是
rediss://
,是的,它工作稳定。

© www.soinside.com 2019 - 2024. All rights reserved.