【问题标题】:Close a Redis connection based on Node.js Event loop基于 Node.js 事件循环关闭 Redis 连接
【发布时间】:2018-06-14 22:46:31
【问题描述】:

问题/我是如何遇到的

我正在 Node.JS 中编写一个批处理 Lambda 函数,它在两个不同的地方调用 Redis。一些批处理项目可能永远不会到达第二个 Redis 调用。这一切都是异步发生的,所以如果我在批处理队列为空时立即关闭连接,任何未来的 Redis 调用都会失败。如何关闭连接?

我的尝试

我目前在做什么

一旦批处理队列为空,我调用:

intervalId = setInterval(closeRedis, 1000);

我关闭Redis连接并在超时后清除回调中的间隔:

function closeRedis() {
    redis.client('list', (err, result) => {
        var idle = parseClientList(result, 'idle');

        if (idle > timeout) {
            redis.quit();
            clearInterval(intervalId);
        }
    });
}

这种方法主要是有效的,但如果只是检查超时,仍然有可能其他进程正在进行,并且将来可能会进行 Redis 调用。当事件循环中只剩下一个空闲连接时,我想关闭连接。有没有办法做到这一点?

【问题讨论】:

    标签: node.js redis aws-lambda node-redis


    【解决方案1】:

    我最终使用了 process._getActiveHandles()。一旦批处理队列为空,我设置一个间隔,每半秒检查一次,如果只剩下最少的进程。如果是这样,我取消引用 redisClient。

    redisIntervalId = setInterval(closeRedis, 500);
    
    // close redis client connection if it's the last required process
    function closeRedis() {
        // 2 core processes plus Redis and interval
        var minimumProcesses = 4;
        if (process._getActiveHandles().length > minimumProcesses)
            return;
    
        clearInterval(redisIntervalId);
        redisClient.unref();
    }
    

    这种方法的优点是我可以确定 Redis 客户端不会在其他重要进程正在运行时关闭连接。我还可以确定,在完成所有重要流程后,客户端不会让事件循环保持活动状态。

    缺点是 _getActiveHandles() 是一个未记录的节点函数,因此它可能会在以后被更改或删除。此外,unref() 是实验性的,在关闭连接时不会考虑某些 Redis 命令。

    【讨论】:

    • 如果你正在开发一个 lambda 函数,你可以设置 context.callbackwaitsforemptyeventloop = false 来结束函数执行而不等待连接关闭。
    猜你喜欢
    • 2014-04-18
    • 2012-07-10
    • 2013-07-07
    • 2022-11-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多