如何在Nest.js中使用Cache Manager处理Redis服务器断开连接问题
问题
在Nest.js中通过Cache Manager集成Redis,已配置重连策略,但Redis服务器意外终止时,Nest.js服务器也会随之关闭,重连逻辑未生效。需实现Redis断开时Nest.js自动重试Socket连接。
原配置代码:
CacheModule.registerAsync<RedisClientOptions>({ imports: [ConfigModule], inject: [ConfigService, WINSTON_MODULE_PROVIDER], useFactory: async (configService: ConfigService, logger: Logger) => { const store = await redisStore({ socket: { host: configService.get<string>('REDIS_HOST'), port: parseInt(configService.get<string>('REDIS_PORT')!), reconnectStrategy: (times) => { logger.error(`Attempting to reconnect to redis: ${times} times`); if (times > 5) { return false; } return Math.min(times * 50, 2000); }, }, username: configService.get<string>('REDIS_USERNAME'), password: configService.get<string>('REDIS_PASSWORD'), }); return { store: { create: () => store as unknown as CacheStore, }, }; }, isGlobal: true, })
解决方案
问题核心在于模块初始化阶段就提前创建Redis连接,一旦Redis不可用,await redisStore会抛出未捕获异常,直接导致Nest.js进程崩溃。调整方案如下:
- 将Redis store的创建逻辑移到
create函数内部,延迟连接初始化到首次使用缓存时 - 监听Redis客户端的
error事件,避免未捕获异常终止进程 - 优化重连策略的日志和重试逻辑
修改后的代码:
CacheModule.registerAsync<RedisClientOptions>({ imports: [ConfigModule], inject: [ConfigService, WINSTON_MODULE_PROVIDER], useFactory: async (configService: ConfigService, logger: Logger) => { return { store: { create: async () => { const store = await redisStore({ socket: { host: configService.get<string>('REDIS_HOST'), port: parseInt(configService.get<string>('REDIS_PORT')!), reconnectStrategy: (times) => { logger.error(`尝试重连Redis:第${times}次`); // 可根据业务需求调整最大重试次数 if (times > 10) { logger.error('Redis重连次数已达上限,停止重试'); return false; } // 指数退避式重试间隔,避免频繁请求 return Math.min(times * 100, 2000); }, }, username: configService.get<string>('REDIS_USERNAME'), password: configService.get<string>('REDIS_PASSWORD'), }); // 捕获Redis客户端错误,防止进程因未处理异常退出 store.client.on('error', (err) => { logger.error(`Redis客户端错误:${err.message}`); }); // 重连状态日志 store.client.on('reconnecting', () => { logger.warn('Redis正在尝试重连...'); }); // 连接成功日志 store.client.on('connect', () => { logger.log('Redis连接成功'); }); return store as unknown as CacheStore; }, }, }; }, isGlobal: true, })
关键说明
- 延迟连接初始化:把
redisStore的创建放到create函数里,Nest.js会在第一次调用缓存服务时才尝试建立Redis连接,避免模块加载阶段因Redis不可用导致崩溃。 - 异常捕获:通过
store.client.on('error')监听所有Redis客户端错误,确保异常被捕获处理,不会扩散到Nest.js主进程。 - 重连策略优化:调整重试间隔为指数退避(每次重试间隔递增),同时增加日志输出,便于排查重连状态。
内容的提问来源于stack exchange,提问作者CrimsonFoot
相关产品推荐
相关产品推荐

