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

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();
    });
};

你所说的客户端是指连接吗?还是由redis.createClient()返回的客户端? - verybadalloc
哦,是的,连接。基本上,“client = redis.createClient();”。 - shaunlim
2个回答

6

从设计和性能方面考虑,最好创建一个客户端并在整个应用程序中使用它。在node中实现这一点相当容易,我假设您正在使用npm包redis

首先,创建一个名为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集群。在数千个请求之后,由于redis故障,请求失败了。 - dn_c

2
使用多个连接可能是根据应用程序对Redis的使用方式而需要的。
例如,一旦连接被用于监听pub/sub频道,那么它只能用于此目的,不能用于其他目的。根据SUBSCRIBE的文档:
“一旦客户端进入订阅状态,就不应该发出任何其他命令,除了额外的SUBSCRIBEPSUBSCRIBEUNSUBSCRIBEPUNSUBSCRIBE 命令。”
因此,如果您的应用程序需要同时订阅通道并将Redis用作通用值缓存,则至少需要两个客户端:一个用于订阅通道,另一个用于将Redis用作缓存。
还有一些Redis命令是阻塞式的,例如BLPOP。繁忙的Web服务器通常同时回复多个请求。假设对于回答请求A,服务器使用其Redis客户端发出阻塞命令。然后请求B来了,服务器需要用非阻塞命令回答Redis,但是客户端仍在等待为请求A发出的阻塞命令完成。现在请求B的响应会被另一个请求延迟。可以通过为第二个请求使用不同的客户端来避免这种情况。
如果您不使用需要多个连接的任何设施,则可以且应该仅使用一个连接。
如果您使用Redis的方式需要多个连接,并且只需要连接列表而不需要复杂的连接管理,则可以创建自己的工厂函数:它将调用redis.createClient()并在返回之前保存客户端。然后在关闭时,可以遍历保存的客户端列表并将其关闭。不幸的是,node-redis没有提供此内置功能。
如果您需要比上述工厂函数更复杂的客户端管理,则管理创建的多个连接的典型方法是使用连接池,但node-redis没有提供连接池。我通常通过Python代码访问Redis,因此我没有Node.js库的推荐,但npm搜索显示出了很多候选项。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接