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
上的文档:
一旦客户端进入订阅状态,它就不应该发出任何其他命令,除了额外的
SUBSCRIBE
、PSUBSCRIBE
、UNSUBSCRIBE
和PUNSUBSCRIBE
命令。
因此,如果您的应用程序需要订阅频道并且使用 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,何时关闭连接?