如何使用缓存管理器处理nest.js中的redis服务器断开连接?

问题描述 投票:0回答:1

因此,我使用

nest.js
redis
中设置缓存管理器,如下代码所示。

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
服务器由于某种原因终止时,
nest.js
服务器也会关闭。

重试逻辑实际上不起作用。我希望我的

nest.js
服务器在
socket
服务器关闭时重试
redis
连接。

无论我用谷歌搜索这个问题多久,我都找不到解决方案。你们能帮我吗?

caching redis nestjs
1个回答
0
投票

实际上我使用一些软件包解决了这个问题:

ioredis
@tirke/node-cache-manager-ioredis

我使用第二个包只是因为打字。文档不是那样的,所以我需要一些自动完成的指南。

棘手的部分是将

redis
集成到
Nest.js
CacheModule中。 官方文档中的指南使用
cache-manager-redis-store
,它基于
redis
包。然而,
redis
包并没有真正提供任何重试选项。

socket
类型的
RedisClientOption
键中有重试选项,但不起作用。

无论如何,我用上面提到的我使用的包编写了这个代码片段,它完全有效,并且当连接从一开始就不存在或在应用程序运行时中间终止时它会重试。

如果有人面临这个困难,我希望这会有所帮助。

import Redis from 'ioredis';
import { ioRedisStore } from '@tirke/node-cache-manager-ioredis';

// ... code 
CacheModule.registerAsync({
      imports: [ConfigModule],
      inject: [ConfigService],
      useFactory: async (configService: ConfigService) => {
        const redisClient = new Redis({
          host: configService.get<string>('REDIS_HOST'),
          port: parseInt(configService.get<string>('REDIS_PORT')!, 10),
          username: configService.get<string>('REDIS_USERNAME'),
          password: configService.get<string>('REDIS_PASSWORD'),
          retryStrategy: (times) => {
            if (times > 600) {
              return null; // Do not retry further
            }
            return 1000;
          },
        });

        redisClient.on('error', (err) => {
          logger.error('Redis error:', err);
        });

        return {
          store: ioRedisStore({
            redisInstance: redisClient,
          }),
        };
      },
      isGlobal: true,
    })
// ... code
© www.soinside.com 2019 - 2024. All rights reserved.