하위 서비스들에서 각각 레디스 클라이언트를 사용하기 위해서 어떤 방법이 있을까 고민해보았다.
하위 서비스들이 상속받을 RedisClient 클래스를 구현.
host, port 등 연결에 관련된 생성자만 있는 클래스
import Redis from 'ioredis';
class RedisClient {
constructor(config) {
this.client = new Redis({
host: config.host || 'localhost',
port: config.port || 6379,
password: config.password,
});
this.client.on('error', (err) => {
console.error('Redis error: ', err);
});
this.client.on('connect', () => {
console.log('Redis connect');
});
}
getClient() {
return this.client;
}
async quit() {
await this.client.quit();
}
}
유틸 함수 등을 각 서비스의 RedisClient에서 메소드로 구현
e.g ) 로비 서버 -> LobbyRedisClient extends RedisClient
export class LobbyRedisClient extends BaseRedisClient {
constructor(config) {
super(config);
this.prefix = 'lobby';
}
async addUserToLobby(lobbyId, userId) {
const key = `${this.prefix}:${lobbyId}:users`;
await this.client.sadd(key, userId);
}
}
클라이언트 인스턴스 생성 및 사용
import { LobbyRedisClient, UserRedisClient } from '@repo/common/utils/redis/clients';
const redisConfig = {
host: process.env.REDIS_HOST,
port: process.env.REDIS_PORT,
password: process.env.REDIS_PASSWORD
};
const server = new LobbyServer(SERVER_NAME, SERVER_PORT);
server.lobbyRedis = new LobbyRedisClient(redisConfig);
server.userRedis = new UserRedisClient(redisConfig);
하위 서비스들이 상속받을 RedisClient 클래스를 구현.
import Redis from 'ioredis';
class RedisClient {
constructor(config) {
this.client = new Redis({
host: config.host || 'localhost',
port: config.port || 6379,
password: config.password,
});
this.client.on('error', (err) => {
console.error('Redis error: ', err);
});
this.client.on('connect', () => {
console.log('Redis connect');
});
}
getClient() {
return this.client;
}
async quit() {
await this.client.quit();
}
}
유틸 함수들을 가지고 있는 RedisUtil 클래스 구현
class RedisUtil {
constructor(redisClient) {
this.client = redisClient;
this.prefix = {
USER: 'user',
LOBBY_USER: 'lobbyUser',
LOBBY_ROOM: 'lobbyRoom',
ROOM: 'room',
};
}
async createUserToSession(userData) {
const key = `${this.prefix.USER}:${userData.userId}`;
await this.client.hset(key, {
userId: userData.userId,
nickname: userData.nickname,
location: userData.location,
});
await this.client.expire(key, 1800);
}
async deleteUserToSession(userId) {
const key = `${this.prefix.USER}:${userId}`;
await this.client.del(key);
}
// 여러 유틸 함수 .....
}
하위 서비스에서 사용
import { RedisClient, RedisUtil } from '@repo/common/classes';
const redisClient = new RedisClient({
host: process.env.REDIS_HOST,
port: process.env.REDIS_PORT,
password: process.env.REDIS_PASSWORD
}).getClient();
const redis = new RedisUtil(redisClient);
// 사용례
await redis.createRoom()
현재로서는 Redis 관련 부분은 한 사람이 맡는게 최선이고 시간을 절약할 수 있을 것 같아서
혼자 여러 유틸 함수를 미리 구현해놓고 필요한 것만 가져다 사용하는 방법으로 채택했다.