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

Posted

技术标签:

【中文标题】Node.js:关闭所有 Redis 客户端【英文标题】:Node.js: Closing all Redis clients on shutdown 【发布时间】:2014-01-20 14:47:09 【问题描述】:

今天,我将 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.createClient()返回的客户端? 哦,是的,连接。基本上,“client = redis.createClient();” 【参考方案1】:

在设计和性能方面,最好创建一个客户端并在您的应用程序中使用它。这在节点中很容易做到。我假设您使用的是 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();
        );
    );
;

【讨论】:

我正在使用 redis-cluster。上千次请求后,由于redis失败,请求失败【参考方案2】:

根据应用程序使用 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 显示了相当多的候选者。

【讨论】:

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

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

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

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

使 Node.js Redis 客户端的 .multi() 和 .batch() 在结果中返回错误以进行测试

如何在node js中配置redis客户端

Node.js - Redis 教程 [关闭]