You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Node.js redis@4.2.0在AWS Lambda中的重连策略异常问题咨询

问题背景

我已将Redis客户端升级至4.2.0版本,并在AWS Lambda中编写了如下代码:

import * as redis from "redis";
export const handler = async (
        event: APIGatewayEvent, context: Context, callback: APIGatewayProxyCallback
    ) => {
        try {
            console.log(`Lambda triggered with event: ${JSON.stringify(event)}`);
            context.callbackWaitsForEmptyEventLoop = false;
            const redisClient = redis.createClient({
                socket: {
                    host: '127.0.0.1',
                    port: 6379,
                    reconnectStrategy: function (retriesAttemptedSoFar: number): number | Error {
                        if (retriesAttemptedSoFar > 3) {
                            // End reconnecting with error
                            return new Error(`Redis retry attempt=${retriesAttemptedSoFar}`);
                        }
                        console.info(` try reconnect after ${Math.min(retriesAttemptedSoFar * 10, 30)}ms`);
                        // reconnect after
                        return Math.min(retriesAttemptedSoFar * 10, 30);
                    }
                },
            });
            redisClient.on('ready', () => {
                console.log(`Got "ready" event from Redis. Connection established.`);
            });
            redisClient.on('connect', () => {
                console.log(`Got "connect" event from Redis. Stream is connected to the server`);
            });
            redisClient.on('error', (err) => {
                console.log(`Got an ERROR from Redis. Details: ${err.message}`);
            });
            await redisClient.connect();
            let serverStates : string[] = [];
            const MAX_RETRIES = 3;
            let i = 0;
            while (i < MAX_RETRIES) {
                try {
                    serverStates = await redisClient.lRange('123', 0, -1);
                } catch (e) {
                    i++;
                    const logMessage = i < MAX_RETRIES ?
                        `attempt ${i}: Failed to store message. Trying again...` :
                        `attempt ${i}: Failed to store message. All attempts failed`;
                    console.warn(logMessage);
                    await new Promise(resolve => setTimeout(resolve, 10));
                }
            }
            if (i >= MAX_RETRIES) {
                throw new Error('Exceeded Max Attempts to store message in Redis');
            }
            console.log(`ServerStates: ${JSON.stringify(serverStates)}`);

            console.log(`${JSON.stringify(event)} Lambda finished successfully`);
            callback(null, {
                statusCode: 200,
                body: 'theResult'
            });
        } catch (e) {
            const error = e as Error;
            console.error(`Lambda execution failed. Got error: ${error.message}`);
            callback(error);
        }
    }

运行中观察到以下现象:

  • 未指定reconnectStrategy且Redis连接失败时,代码会无限尝试重连;
  • 指定reconnectStrategy后,Redis连接失败时,Lambda会在3次重连后进入catch代码块,符合预期。

请问为何未配置重连策略时会出现无限重连的情况?


解答

这是因为Redis Node.js客户端(v4.x版本)的默认重连策略就是无限重试。

当不手动指定reconnectStrategy时,客户端会使用内置的默认逻辑:每次连接失败后,会按照固定间隔(默认100ms)不断尝试重连,不会主动终止重试流程。这种设计是为了适配大多数长连接场景,保证客户端在网络波动或服务临时不可用时能自动恢复连接。

而自定义reconnectStrategy后,客户端会严格遵循你定义的逻辑执行:当重试次数超过3次时,返回Error对象,客户端会停止重连并抛出错误,最终被Lambda的catch块捕获,符合预期。

另外需要注意,代码中设置的context.callbackWaitsForEmptyEventLoop = false会让Lambda在回调执行完成后立即结束函数,不会等待事件循环中的异步任务(比如Redis的重连尝试),但核心原因还是客户端默认的无限重试策略。


内容的提问来源于stack exchange,提问作者Ida Amit

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.21 23:57:20