From 325141761341542466e559b7a74e6c7c297690a0 Mon Sep 17 00:00:00 2001 From: Gabriel Mata Date: Mon, 28 Oct 2024 17:30:31 -0500 Subject: [PATCH 1/2] refactor: Refactor redis module to dynamically build the connection to the Redis cluster --- README.md | 2 ++ packages/server/docker-compose.yml | 4 ++- packages/server/src/config/app.config.ts | 29 +++++++++++++--- packages/server/src/modules/redis.module.ts | 38 ++++++++++++--------- 4 files changed, 52 insertions(+), 21 deletions(-) diff --git a/README.md b/README.md index 6af409b..c5e7fcc 100644 --- a/README.md +++ b/README.md @@ -15,6 +15,8 @@ Service designed for the management and storage of messaging for the Message Pic | `FCM_SERVICE_BASE_URL` | The base URL for the push notification service. | _Not set by default_ | | `MONGODB_URI` | The MongoDB URI for connecting to the database. | `mongodb://user:password@localhost:27017/MessagePickupRepository` | | `REDIS_TYPE` | Allows set redis type works `single` or `cluster` | `single` | +| `REDIS_NODES` | A comma-separated list of Redis nodes' `host:port` for cluster mode. Only required if `REDIS_TYPE` is set to `cluster`. Ignored in single mode. | `redis-node1:6379,redis-node2:6379,redis-node3:6379` | +| `REDIS_NATMAP` | The NAT mapping for Redis nodes in `externalAddress:host:port` format. Required for Redis cluster configurations where external IPs or ports are mapped to internal Redis node addresses. | `10.0.0.1:6379:redis-node1:6379,10.0.0.2:6379:redis-node2:6379` | | `REDIS_URL` | The Redis database URL for connecting to the server.(only single mode) | `redis://localhost:6379` | | `THRESHOLD_TIMESTAMP` | Allows set threshold time to execute message persist module on milisecond | `60000` | diff --git a/packages/server/docker-compose.yml b/packages/server/docker-compose.yml index cd0d1af..4496f0b 100644 --- a/packages/server/docker-compose.yml +++ b/packages/server/docker-compose.yml @@ -10,7 +10,9 @@ services: - APP_PORT=3500 - WS_PORT=3100 - MONGODB_URI=mongodb://cloud-agent:cloud-agent@mongodb:27017/MessagePickupRepository - - REDIS_TYPE=single + - REDIS_TYPE=cluster + - REDIS_NODES=192.168.10.13:6371,192.168.10.13:6372,192.168.10.13:6373,192.168.10.13:6374,192.168.10.13:6375,192.168.10.13:6376 + - REDIS_NATMAP=172.29.0.2:6379:192.168.10.13:6371,172.29.0.3:6379:192.168.10.13:6372,172.29.0.4:6379:192.168.10.13:6373,172.29.0.5:6379:192.168.10.13:6374,172.29.0.6:6379:192.168.10.13:6375,172.29.0.7:6379:192.168.10.13:6376 - REDIS_URL=redis://redis:6379 restart: always ports: diff --git a/packages/server/src/config/app.config.ts b/packages/server/src/config/app.config.ts index 424da28..5a2c484 100644 --- a/packages/server/src/config/app.config.ts +++ b/packages/server/src/config/app.config.ts @@ -35,13 +35,34 @@ export default registerAs('appConfig', () => ({ mongoDbUri: process.env.MONGODB_URI || 'mongodb://cloud-agent:cloud-agent@localhost:27017/MessagePickupRepository', /** - * The Redis database URL for connecting to the Redis server. - * Defaults to a specified local Redis instance if REDIS_URL is not set in the environment variables. + * Defines the Redis mode, which can be 'single' or 'cluster'. + * Defaults to 'single' if REDIS_TYPE is not set in the environment variables. * @type {string} */ - redisDbUrl: process.env.REDIS_URL || 'redis://192.168.100.84:6379', + redisType: process.env.REDIS_TYPE || 'single', - redisType: process.env.REDIS_TYPE || 'cluster', + /** + * A comma-separated list of Redis nodes in 'host:port' format, used in cluster mode. + * Only relevant if REDIS_TYPE is set to 'cluster'. + * @type {string | undefined} + */ + redisNodes: process.env.REDIS_NODES, + + /** + * The NAT mapping for Redis nodes, defined in 'externalAddress:host:port' format. + * Useful for Redis cluster configurations with external IP mappings. + * @type {string | undefined} + */ + redisNatmap: process.env.REDIS_NATMAP, + /** + * The Redis database URL for connecting to the Redis server Single Mode. + * Defaults to a specified local Redis instance if REDIS_URL is not set in the environment variables. + * @type {string} + */ + redisDbUrl: process.env.REDIS_URL || 'redis://localhost:6379', + /** + *Allows set threshold time to execute messagePersist module on milisecond + */ thresholdTimestamp: parseInt(process.env.THRESHOLD_TIMESTAMP) || 60000, })) diff --git a/packages/server/src/modules/redis.module.ts b/packages/server/src/modules/redis.module.ts index 74c130f..18a7fd3 100644 --- a/packages/server/src/modules/redis.module.ts +++ b/packages/server/src/modules/redis.module.ts @@ -10,25 +10,31 @@ import { ConfigModule, ConfigService } from '@nestjs/config' useFactory: (configService: ConfigService): RedisModuleOptions => { const redisType = configService.get('appConfig.redisType', 'single') if (redisType === 'cluster') { + const nodes = configService + .get('appConfig.redisNodes', '') + .split(',') + .map((node) => { + const [host, port] = node.split(':') + return { host, port: parseInt(port, 10) } + }) + + const natMap = configService + .get('appConfig.redisNatmap', '') + .split(',') + .reduce( + (map, entry) => { + const [externalAddress, externalPort, internalHost, internalPort] = entry.split(':') + map[`${externalAddress}:${externalPort}`] = { host: internalHost, port: parseInt(internalPort, 10) } + return map + }, + {} as Record, + ) + return { type: 'cluster', - nodes: [ - { host: 'localhost', port: 6371 }, - { host: 'localhost', port: 6372 }, - { host: 'localhost', port: 6373 }, - { host: 'localhost', port: 6374 }, - { host: 'localhost', port: 6375 }, - { host: 'localhost', port: 6376 }, - ], + nodes, options: { - natMap: { - '172.29.0.2:6379': { host: 'localhost', port: 6371 }, - '172.29.0.3:6379': { host: 'localhost', port: 6372 }, - '172.29.0.4:6379': { host: 'localhost', port: 6373 }, - '172.29.0.5:6379': { host: 'localhost', port: 6374 }, - '172.29.0.6:6379': { host: 'localhost', port: 6375 }, - '172.29.0.7:6379': { host: 'localhost', port: 6376 }, - }, + natMap, redisOptions: { connectTimeout: 10000, // Maximum wait time for connection in milliseconds maxRetriesPerRequest: 5, // Maximum number of retries per request From 46d066eef753ac53b94c24fce92a654206da3b6d Mon Sep 17 00:00:00 2001 From: Gabriel Mata Date: Wed, 30 Oct 2024 14:28:20 -0500 Subject: [PATCH 2/2] feat: add Logger Redis module --- packages/server/src/modules/redis.module.ts | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/packages/server/src/modules/redis.module.ts b/packages/server/src/modules/redis.module.ts index 18a7fd3..b175de3 100644 --- a/packages/server/src/modules/redis.module.ts +++ b/packages/server/src/modules/redis.module.ts @@ -1,4 +1,4 @@ -import { Module } from '@nestjs/common' +import { Module, Logger } from '@nestjs/common' import { RedisModule, RedisModuleOptions } from '@nestjs-modules/ioredis' import { ConfigModule, ConfigService } from '@nestjs/config' @@ -8,7 +8,9 @@ import { ConfigModule, ConfigService } from '@nestjs/config' imports: [ConfigModule], inject: [ConfigService], useFactory: (configService: ConfigService): RedisModuleOptions => { + const logger = new Logger('RedisModule') const redisType = configService.get('appConfig.redisType', 'single') + logger.log(`[RedisModule] Configuring Redis with type: ${redisType}`) if (redisType === 'cluster') { const nodes = configService .get('appConfig.redisNodes', '') @@ -17,7 +19,7 @@ import { ConfigModule, ConfigService } from '@nestjs/config' const [host, port] = node.split(':') return { host, port: parseInt(port, 10) } }) - + logger.debug(`[RedisModule] Cluster Nodes: ${nodes}`) const natMap = configService .get('appConfig.redisNatmap', '') .split(',') @@ -29,7 +31,7 @@ import { ConfigModule, ConfigService } from '@nestjs/config' }, {} as Record, ) - + logger.debug(`[RedisModule] Cluster Nat: ${nodes}`) return { type: 'cluster', nodes,