Node.js:关闭时关闭所有Redis客户端

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Node.js:关闭时关闭所有Redis客户端相关的知识,希望对你有一定的参考价值。

今天,我将Redis集成到我的node.js应用程序中,并将其用作会话存储。基本上,在成功验证后,我将相应的用户对象存储在Redis中。

当我在身份验证后收到http请求时,我尝试使用哈希从Redis中检索用户对象。如果检索成功,则表示用户已登录并且可以完成请求。

将用户对象存储在Redis中的行为和检索发生在两个不同的文件中,因此我在每个文件中都有一个Redis客户端。

问题1:两个Redis客户端是否可以,每个文件一个?或者我应该只实例化一个客户端并在应用程序的所有区域使用它?

问题2:node-redis库是否提供了显示已连接客户端列表的方法?如果是这样,我将能够遍历列表,并在服务器关闭时为每个列表调用client.quit()。

顺便说一句,这就是我实现服务器“正常关闭”的方式:

//Gracefully shutdown and perform clean-up when kill signal is received
process.on('SIGINT', cleanup);
process.on('SIGTERM', cleanup);

function cleanup() {
    server.stop(function() {
        //todo: quit all connected redis clients

        console.log('Server stopped.');

        //exit the process
        process.exit();
    });
};
答案

应用程序如何使用Redis可能需要使用多个连接。

例如,一旦连接被用于收听发布/订阅频道的目的,那么它只能用于此而不能用于其他任何内容。根据SUBSCRIBE的文档:

一旦客户端进入订阅状态,除了额外的SUBSCRIBEPSUBSCRIBEUNSUBSCRIBEPUNSUBSCRIBE命令之外,它不应该发出任何其他命令。

因此,如果您的应用程序需要订阅频道并使用Redis作为通用值缓存,那么它至少需要两个客户端:一个用于订阅频道,一个用于将Redis用作缓存。

还有像BLPOP一样阻塞的Redis命令。繁忙的Web服务器通常一次回复多个请求。假设为了回答请求A,服务器使用其Redis客户端发出阻塞命令。然后请求B来了,服务器需要使用非阻塞命令来回答Redis,但客户端仍在等待为请求A完成的阻塞命令。现在,对请求B的响应被另一个请求延迟。通过为第二个请求使用不同的客户端可以避免这种情况。

如果您不使用任何需要多个连接的设施,那么您可以而且应该只使用一个连接。

如果您使用Redis的方式是需要多个连接,并且您只需要一个连接列表但没有复杂的连接管理,您可以创建自己的工厂函数:它会在返回之前调用redis.createClient()并保存客户端。然后在关机时,您可以查看已保存的客户端列表并关闭它们。不幸的是,node-redis没有内置这样的功能。

如果您需要比上述工厂功能更复杂的客户端管理,那么管理创建的多个连接的典型方法是使用连接池,但node-redis不提供连接池。我通常通过Python代码访问Redis,所以我没有推荐Node.js库,但npm search显示了不少候选人。

另一答案

在设计和性能方面,最好创建一个客户端并在整个应用程序中使用它。在节点中这很容易做到。我假设你正在使用redis npm包。

首先,使用以下内容创建名为redis.js的文件:

const redis = require('redis');

const RedisClient = (function() {
    return redis.createClient();
})();

module.exports = RedisClient

然后,在文件set.js中说,你会这样使用它:

const client = require('./redis');
client.set('key', 'value');

然后,在index.js文件中,您可以导入它并在退出时关闭连接:

const client = require('./redis');

process.on('SIGINT', cleanup);
process.on('SIGTERM', cleanup);

function cleanup() {
    client.quit(function() {
        console.log('Redis client stopped.');
        server.stop(function() {
            console.log('Server stopped.');
            process.exit();
        });
    });
};
另一答案

我认为只有一个连接更好。

module.exports = redis.createClient();

管理多个连接是不必要的。

对于redis。你可以使用redis-sentinel。

顺便说一句,你也可以使用ioredis

以上是关于Node.js:关闭时关闭所有Redis客户端的主要内容,如果未能解决你的问题,请参考以下文章

Node.js + Express + Redis,何时关闭连接?

Node.js - Redis 教程 [关闭]

如何在 AngularJS 客户端和 Node.js 服务器之间重用代码 [关闭]

为啥 Node.js 是单线程的? [关闭]

为啥 Node.js 是单线程的? [关闭]

当服务器关闭/崩溃时,Node JS 会自动重启所有永远的 JS 进程