Ioredis调用connect()重连时未重置重试次数的问题如何解决?
ioredis手动重连重试次数不重置问题修复方案
问题根因
ioredis传入retryStrategy的times参数是当前客户端实例生命周期内的累计重试次数,不会因为调用client.connect()手动重连就自动清零,因此首次连接失败后次数会持续累加,导致后续手动触发的重连直接触发阈值,无法享受完整的重试次数。
修复方案
方案一:自行维护重试计数器(推荐)
无需修改现有业务逻辑,仅需调整Redis初始化配置,新增计数器和连接监听事件即可:
// 自定义重试计数器,脱离ioredis内置计数逻辑 let redisRetryCount = 0; var client = new Redis({ port: 63xx, // Redis port host: REDISHOST, // Redis host family: 4, // 4 (IPv4) or 6 (IPv6) db: 0, lazyConnect: true, connectTimeout: 3000, retryStrategy: function () { redisRetryCount += 1; if (redisRetryCount > 3) { logger.error("redisRetryError", 'Redis reconnect exhausted after 3 retries.'); // 重试失败后重置计数器,方便下次手动重连计数 redisRetryCount = 0; return null; } return 200; } }); // 连接成功时重置计数器,保证下一次重连从0开始计数 client.on('connect', () => { redisRetryCount = 0; });
方案二:重连时重新实例化Redis客户端
如果不想额外维护计数器,可在每次检测到连接断开时,销毁旧实例并新建客户端,新实例的重试次数会自动清零:
static async getData(key) { try { // if connection is ended then we are trying to reconnect it. if (client.status === 'end') { await logger.warning(`reconnectingRedis`, 'Redis is not connected. Trying to reconnect to Redis!'); // 销毁旧实例,释放资源 client.disconnect(); // 重新初始化客户端,内置计数自动清零 client = new Redis({ port: 63xx, host: REDISHOST, family: 4, db: 0, lazyConnect: true, connectTimeout: 3000, retryStrategy: function (times) { if (times > 3) { logger.error("redisRetryError", 'Redis reconnect exhausted after 3 retries.'); return null; } return 200; } }); await client.connect(); } let output = await client.get(key); return JSON.parse(output); } catch (error) { ApiError.throw(error, errorCode.REDIS_GET_ERROR_CODE); } }
两种方案都可以实现每次重连都享有4次(含初始连接)的重试机会,方案一对现有代码侵入性更低,性能开销更小,优先推荐使用。
内容的提问来源于stack exchange,提问作者Nandan Raj
相关产品推荐
相关产品推荐

