10

今天,我将 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();
    });
};
4

2 回答 2

6

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

首先,创建一个名为的文件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();
        });
    });
};
于 2019-04-09T03:41:31.867 回答
2

应用程序使用 Redis 的方式可能需要使用多个连接。

例如,一旦连接被用于监听 pub/sub 频道,那么它只能用于此目的而不能用于其他目的。根据以下文档SUBSCRIBE

一旦客户端进入订阅状态,它就不应该发出任何其他命令,除了附加SUBSCRIBEPSUBSCRIBE、、UNSUBSCRIBEPUNSUBSCRIBE命令。

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

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

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

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

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

于 2019-04-10T11:15:58.793 回答