커리큘럼
home
React
home
🛹

Redis pub/sub 중복 구독 문제 (1)

문제

NestJS에서 Redis Pub/Sub을 사용해 실시간 알림을 구현하던 중, 동일한 메시지가 클라이언트에 중복 전달되는 문제가 발생했습니다.

원인 분석

기존 구현에서는 클라이언트가 WebSocket을 통해 서버에 연결될 때마다 handleConnection 메서드에서 Redis 채널에 대한 구독이 이루어졌습니다. 각 클라이언트가 연결될 때마다 구독이 중복으로 발생해, 동일한 메시지가 여러 번 수신되며 중복된 이벤트로 처리되었습니다. 이로 인해 서버와 클라이언트 간의 성능 저하 및 불필요한 네트워크 트래픽이 발생했습니다.

해결 방법

중복 구독 문제를 해결하기 위해, 구독 로직을 클라이언트의 연결 시점이 아닌, NotificationGateway 클래스가 초기화될 때 한 번만 실행되도록 변경했습니다. 이렇게 함으로써, 여러 클라이언트가 연결되더라도 구독이 중복으로 발생하지 않도록 하였습니다.
@WebSocketGateway({ cors: { origin: '*', } }) export class NotificationGateway { @WebSocketServer() server: Server; private static isSubscribed = false; constructor(private readonly redisService: RedisService) { if (!NotificationGateway.isSubscribed) { this.subscribeToRedis(); // 클래스 초기화 시 구독 수행 NotificationGateway.isSubscribed = true; } } private async subscribeToRedis() { await this.redisService.subscribe('notifications', (message: string) => { const parsedMessage = JSON.parse(message); this.server.emit('notifications', parsedMessage); }); } . . .
JavaScript
복사

해결된 방법 및 효과

1.
구독 시점 변경: NotificationGateway 클래스가 초기화될 때, 즉 서버가 시작될 때 구독이 한 번만 설정되도록 변경했습니다. 이로 인해 모든 클라이언트에 대해 동일한 Redis 구독을 공유하고, 중복 구독을 방지했습니다.
2.
중복 수신 문제 해결: 구독이 한 번만 설정되었기 때문에, 여러 클라이언트가 연결되더라도 중복된 메시지 수신 없이, Redis에서 수신된 알림을 적절히 받을 수 있게 되었습니다.

결론

Redis Pub/Sub의 구독 로직을 서버 초기화 시점으로 이동시켜 중복 구독 문제를 해결함으로써, 실시간 알림 및 채팅 기능에서의 성능과 안정성을 크게 개선할 수 있었습니다. 이를 통해 효율적이고 확장 가능한 시스템을 구축할 수 있었습니다.