Reusing Redis Connection:Socket Closed Unexpected-node-redis

epggiuax  于 12个月前  发布在  Redis
关注(0)|答案(4)|浏览(131)

首先,让我告诉你我是如何在我的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连接可以吗?我的方法有什么问题吗?
1.为什么会发生这种情况?为什么我的套接字意外关闭?
1.有没有一种方法可以捕获这个错误(使用我的方法)或者其他实现Redis连接的好方法?

ecfsfe2w

ecfsfe2w1#

我使用'error'侦听器解决了这个问题。只是侦听它-避免节点应用程序崩溃。

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

字符串

aemubtdh

aemubtdh2#

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

dsf9zpds

dsf9zpds3#

你应该声明一个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中。

pbgvytdp

pbgvytdp4#

我也遇到了同样的问题(Socket Closed Unexpected),但只是在远程Redis服务器上,所以我想可能是TLS有问题。所以我尝试使用redis://而不是rediss://,是的,它工作稳定。

相关问题