개발일지

실시간 채팅 시스템, 왜 서버가 필요할까? – 구조와 아키텍처 설계까지

makeviibe 2025. 7. 15. 15:59

💬 실시간 채팅, 왜 서버가 필요할까?

– 단일 서버부터 멀티 서버 아키텍처까지

안녕하세요, makeviibe입니다.

이번 글에서는 채팅 시스템을 개발할 때 왜 서버가 꼭 필요한지,

그리고 서버가 여러 대일 때 어떻게 아키텍처를 구성해야 하는지에 대해 소개드리려 합니다.

실시간 채팅 기능은 단순히 메시지를 주고받는 것처럼 보이지만,

의외로 서버 역할이 많고, 구조적 고민도 깊이 들어가는 영역입니다.


1️⃣ 채팅 구현에 서버가 필요한 이유

📡 1. 실시간 통신의 중계자 역할

채팅은 Client ↔ Server ↔ Client 구조로 동작합니다.

브라우저나 앱끼리는 직접 연결되지 않고, 항상 서버를 거쳐 메시지를 주고받습니다.

서버의 주요 역할은 다음과 같습니다:

  • 방 관리: 누가 어떤 채팅방에 참여 중인지 관리
  • 메시지 중계: 메시지를 특정 사용자나 방에 브로드캐스트
  • 접속 상태 추적: 사용자 접속/이탈 감지
  • 이전 메시지 히스토리 제공: DB에서 불러와 전달
  • 알림 전송: 푸시 또는 알림 API 연동
  • 보안 제어: 인증 토큰 검증, 권한 체크 등

👉 클라이언트끼리 직접 연결할 수 없는 환경(Web/Mobile)에서는 서버는 필수적입니다.


🧩 2. 상태 관리

  • 누가 어느 방에 들어왔는지
  • 언제 나갔는지
  • 마지막으로 읽은 메시지는 무엇인지
  • → 이런 상태를 유지하려면 서버가 지속적으로 세션/커넥션을 관리해야 합니다.

🗄 3. 데이터 저장과 연동

  • 실시간으로 오간 메시지를 DB에 저장해야 나중에 다시 불러올 수 있고
  • 알림, 통계, 신고/차단 등 기능도 서버-DB 연동 없이는 불가능합니다.

2️⃣ 서버가 여러 대일 때, 어떻게 구성해야 할까?

서비스 규모가 커져서 서버를 여러 대 운영하게 되면

단순한 WebSocket 연결만으로는 해결되지 않습니다.

🖇 대표적인 문제

  • 사용자 A는 1번 서버에 연결, B는 2번 서버에 연결되었을 때
  • → A의 메시지를 B에게 전달하려면 **서버 간 정보 공유(브로드캐스트)**가 필요합니다.

🧱 해결 방법: Pub/Sub 아키텍처 도입

✅ 구조 예시

✅ 활용 기술 예시

  • Socket.IO Adapter: @nestjs/platform-socket.io에서 Redis adapter 사용
  • Redis Pub/Sub: 여러 서버 간 채널을 공유해 실시간 메시지 동기화
  • Sticky Session (선택): 사용자가 항상 같은 서버로 연결되도록 유지

✅ 서버 구성 요소


📌 확장 가능한 구조로 설계하려면

  • Stateless 설계: 서버는 사용자의 상태를 Redis/DB 등 외부에 저장하고 언제든 분산 가능하게
  • Failover 구조: 특정 서버가 죽어도 연결이 유지되도록 로드밸런싱 + 리트라이 정책 적용
  • Queue 연동: 메시지 저장, 푸시 전송 등을 백그라운드로 분리하면 성능 안정화에 유리

✅ 마무리하며

채팅은 단순히 "메시지를 보내는 것"처럼 보여도,

클라이언트 상태 관리, 서버 간 동기화, 히스토리, 인증, 확장성 등 복합적인 요소가 결합된 기능입니다.

- NestJS + Socket.IO

- Redis 기반 멀티 서버 아키텍처

- 클린한 상태 관리와 리소스 해제 처리

이 글이 채팅 시스템을 고민하시는 분들께 구조적인 방향성을 드릴 수 있기를 바랍니다.

궁금하신 내용이 있다면 언제든 댓글이나 문의로 남겨주세요 🙌