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
相关产品推荐
相关产品推荐

