Skip to content

Pearl-K/CoffeeChat-Server

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

33 Commits
 
 
 
 
 
 
 
 

Repository files navigation

CoffeeChat-Server

Motivation

  • 기존에 오프라인 중심이었던 개발자 커피챗을 온라인에서도 편하게 이어갈 수 있도록 만듭니다.
  • 서비스가 제공하는 핵심 가치 중 하나는, 실시간 온라인 커피챗을 기술적으로 원활히 제공하는 것입니다.

Overview & My Role

  • 이 레포지토리는 CoffeeChat Service의 서버 중 실시간 채팅 파트를 분리하여 재구성한 서버입니다.
  • 실시간 커피챗 채팅 구조를 직접 설계하고 실험 결과를 통해 개선했습니다. 주요 책임은 다음과 같습니다:
  1. 실시간 채팅 서비스
  2. User On/Offline Tracking
  3. 인기 게시글 / 인기 순위 / 피드 API 및 캐싱 전략

Refactoring Journey (V1 → V3)

이 프로젝트는 MVP PoC에 초점을 맞춘 V1에서 시작하여 → 메시지 신뢰성과 성능을 끌어올린 V2 → 확장성을 고려한 V3로 개선 중입니다.

Version 핵심 목표 (Goal) 주요 기술/설계 변경점 해결하고자 한 문제
V1 최소 기능 구현 (MVP PoC)
  • WebSocket + Redis Pub/Sub
  • MongoDB
  • 동료들이 직접 기능 검증 및 피드백
  • 50명 이상의 동시 접속자 두고 채팅 시연
V2 메시지 신뢰성 보장, 성능 개선
  • 메시지 브로커 교체 (RabbitMQ)
  • 큐 파티셔닝 도입
  • GC 메트릭 관측
  • Redis Pub/Sub의 메시지 유실 가능성 해결
  • 단일 큐 메시지 적체 현상 개선
V3 수평 확장(Scale-out)이 가능한 구조 구현
  • Redis 세션 공유 저장소 도입
  • MQ를 통한 서버간 느슨한 결합
  • 모니터링 메트릭의 다양화
  • 상태 의존으로 인한 확장 문제 해결
  • 채팅 부하 테스트에서 병목점 파악

Architecture

V1

V1은 실시간 커피챗 기능의 기초 구조를 빠르게 검증하기 위한 MVP(PoC) 단계입니다.

복잡한 메시지 브로커 없이 간단하고 빠르게 도입할 수 있는 Redis Pub/Sub으로 최소한의 실시간 메시징 기능을 구현하는 데 집중했습니다.

실제 50명 이상의 동시 접속자가 참여하는 채팅 시연을 통해 UX 흐름과 메시지 전달 기능을 검토했습니다. 이 과정에서 Redis Pub/Sub의 구조적 한계인 메시지 유실 가능성 및 여러 이슈를 확인했고, 신뢰성과 확장성 확보를 위한 V2로 개선하게 되었습니다.

V2

  • 커피챗 서비스 특성상, 특정 시간대(휴일)에 여러 채팅방에서 동시다발적인 메시지 발송이 발생할 수 있습니다.
  • 이를 가정하여, 대량의 chatroom에서 메시지를 동시에 발행하는 부하 테스트를 수행한 결과, 단일 Queue에 메시지가 집중되며 latency가 증가하는 것을 확인했습니다.
  • 이를 해결하기 위해 아래의 개선 사항을 적용했습니다.
    • chatroomId 해시 기반의 큐 파티셔닝: 메시지를 균등하게 분산하여 단일 큐 병목 완화
    • Queue-Consumer 1:1 mapping: 메시지 순서를 유지하면서 큐 단위 병렬 처리 가능
  • 부하 집중에 따른 hotkey 문제는 발생 가능성이 낮다고 판단했습니다.
    • 커피챗 서비스는 하나의 room 당 최대 4인 이하로 구성
    • 특정 방에 메시지 부하가 집중되는 패턴보다, 전체 chatroom 개수 증가에 따른 부하 패턴이 우세

Technical Decisions & Trade-offs

1. Redis Pub/Sub의 한계

  • Redis Pub/Sub의 메시지 시멘틱은 At Most Once, 네트워크 장애 등 예상치 못한 상황에서 메시지 유실 가능성 이 존재합니다.
  • 서비스 규모가 커질수록 Pub/Sub의 구조적인 한계가 드러납니다.
    • Pub/Sub은 구독자 수(N)에 비례하는 Push 방식(O(N))
    • 채팅방 참여자가 많아질수록 메시지 전송 비용 증가, 지연 위험
    • PSUB: topic을 chatroom.* 와일드카드 방식으로 관리하면, 한 명이 발행한 메시지를 모든 구독자가 수신하여 부하 증대
    • SUB: topic을 chatroom.1처럼 세분화하면, 동적 리스너 등록/해제 처리로 인한 운영 & 코드 복잡도 증가
  • 장애 대응(ex. 메시지 재전송, 복구 로직)을 직접 구현하기보다, 신뢰성있는 메시지 브로커를 도입하는 것이 효율적이라고 판단했습니다.

2. 메시지 브로커 비교 (RabbitMQ vs Kafka)

  1. 빠른 도입과 운영 편의성

    • RabbitMQ는 Spring AMQP 통합 환경을 제공하여 도입하기 쉬움
    • 브로커 UI를 통해 큐 상태, 메시지 적체, 소비 현황을 쉽게 모니터링 가능
  2. ACK 기반의 신뢰성 보장 + DLQ 구축 용이

    • RabbitMQ는 메시지 소비 후 명시적 ACK 방식으로 동작 + 처리 실패를 위한 DLQ 구축과 재처리 로직 구현이 간편함
    • 이에 반해 Kafka는 offset, idempotent 처리 비용이 추가됨
  3. Disk 기반 로그 불필요

    • 메시지를 이미 동기적으로 MongoDB에 저장하고 있기 때문에, Kafka의 commit log 저장은 중복 처리가 될 수 있음

About

개발자를 위한 CoffeeChat Service의 서버 레포지토리입니다.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors