Skip to content

[DOC]서버 아키텍처 리팩토링 계획 #106

@Neo1228

Description

@Neo1228

피드백 1.

현재 아키텍처는 교내 약 80명 수준의 DAU를 기준으로 설계되었습니다. 사전 실사용자 조사겸 단기간 배포임에도 빠르게 사용자가 유입되는 것을 확인했고, 장기적으로는 100명 이상의 접속자가 발생할 것으로 예측했습니다. 하지만 이에 대응하기에는 현재 아키텍처에 문제점이 존재하는 것을 알게 되었습니다.

우선 현재 CATXI 아키텍처 상황 분석

Image

EC2 #1: Nginx + Redis(Docker) + Chat Server
EC2 #2: 채팅  API Server  
EC2 #3: Chat Server

현재 아키텍처를 보면 EC2 #1 은 너무 많은 책임 Docker, Chat Server, Nginx를 가지고 있기 때문에 SPOF(Single Point of Failure)를 가지고 있고, 이로 인해서 이 서버에 문제가 발생하면 모든 서버에서 문제가 발생했습니다. 그리고 현재의 아키텍처는 수평적 확장성에 제약을 가지므로 부하 분산에 비효율성을 가지며 탄력적 확장이 불가능하다는 것을 인지하게 되었습니다.

현재 문제점들

  1. Redis Pub/Sub 미작동: STOMP WebSocket만 사용하여 서버 간 메시지 동기화 안 됨
  2. ip_hash 제한: 동일 IP 사용자가 항상 같은 채팅 서버로만 라우팅
  3. Redis SPOF: EC2 #1의 Docker Redis 장애 시 전체 시스템 중단

해결책으로는...

1. 로드밸런싱 알고리즘 최적화

기존 ip_hash 방식을 least_conn으로 변경하여 서버별 실시간 부하 상태에 따른 동적 트래픽 분산을 구현합니다. 이를 통해 특정 서버에 과부하가 집중되는 문제를 해결할 수 있습니다.

2. 서비스 역할 명확화 및 라우팅 세분화

Nginx 리버스 프록시 기능을 활용한 정교한 라우팅 설정으로 다음과 같이 분리합니다:

  • WebSocket 요청 (/ws, /connect) → 채팅 전용 서버군
  • REST API 요청 (/api) → 일반 API 서버군
  • SSE 요청 (/sse) → 실시간 알림 서버군

3. 수평적 확장성 확보

각 서비스별로 독립적인 스케일 아웃이 가능하도록 구성하여, 트래픽 증가 시 필요한 서비스만 선택적으로 확장할 수 있습니다.

4. SPOF(단일 장애점) 해결

Redis를 EC2 Docker에서 ElastiCache로 분리하여 데이터베이스 레이어의 가용성과 안정성을 크게 향상시킵니다. 이로써 EC2 #1 장애 시에도 채팅 시스템이 정상 작동할 수 있습니다.

EC2 #1: Gateway & Orchestration Server

역할이 단순 로드밸런싱보다 훨씬 복합적:

  • Nginx Reverse Proxy: 지능형 라우팅 (단순 로드밸런싱 아님)
  • SSL 터미네이션: Let's Encrypt 인증서 관리 -> https 적용
  • Health Check Orchestrator: 전체 시스템 상태 모니터링
  • Static File Serving: 프론트엔드 정적 파일 서빙

EC2 #2: Business Logic API Server

채팅 외 API만이 아닌 확장된 역할:

  • Core Business API: 사용자 관리, 인증, 비즈니스 로직
  • Chat REST API: 채팅방 생성/관리, 메시지 히스토리
  • Database Operations: MySQL RDS와의 모든 트랜잭션 처리
  • Redis Caching: 세션 관리 및 캐싱 (채팅 메시지 제외)
  • Background Jobs: 스케줄링, 배치 작업

EC2 #3: Real-time Communication Engine

단순 채팅 서버가 아닌 실시간 통신 전담:

  • WebSocket Manager: STOMP, SockJS 연결 관리
  • Redis Pub/Sub Handler: EC2 #4와의 실시간 메시지 브로드캐스팅
  • SSE (Server-Sent Events): 알림, 상태 업데이트
  • Connection Pool Management: WebSocket 연결 최적화

EC2 #4: Real-time Communication Engine

단순 채팅 서버가 아닌 실시간 통신 전담:

  • WebSocket Manager: STOMP, SockJS 연결 관리
  • Redis Pub/Sub Handler: EC2 #3와의 실시간 메시지 브로드캐스팅
  • SSE (Server-Sent Events): 알림, 상태 업데이트
  • Connection Pool Management: WebSocket 연결 최적화

변경 후 아키텍처

Image

그렇다면 왜 이 구성이 더 나은가? -> 명확한 관심사 분리를 통해서 이전의 발생한 문제점들을 모두 해결할 수 있음.

  • EC2#1: 트래픽 제어 및 시스템 관리
  • EC2#2: 데이터 처리 및 비즈니스 로직
  • EC2#3, EC2#4: 실시간 통신 및 연결 관리

피드백 2.

다음으로 이번에 CATXI 프로젝트에서 발생했던 데이터베이스 스키마 변경 관련 오류들을 통해서, 체계적인 데이터베이스 마이그레이션 전략이 필요로 한다는 것을 느끼게 되었습니다.

해결책으로는...

  1. Flyway를 활용한 자동 마이그레이션
  2. Jenkins 배포 파이프라인에 자동 마이그레이션 검증을 추가
  3. 실시간 모니터링 및 알림(Flyway 마이그레이션 상태 모니터링 컨트롤러를 따로 만들어서 서버 상태 체크 api와 동일하게 배포할때마다 주기적으로 체크)

예상되는 추후 채팅 워크 플로우

1. 사용자A (서버1 연결)  "안녕하세요" 메시지 전송
   
2. 서버1  Redis Pub/Sub "chat" 채널에 메시지 발행
   
3. 서버1, 서버2 모두 Redis에서 메시지 수신
   
4. 서버1  자신에게 연결된 채팅방 참여자들에게 STOMP 전송
   서버2  자신에게 연결된 채팅방 참여자들에게 STOMP 전송
   
5. 사용자B (서버2 연결)  "안녕하세요" 메시지 수신 완료

Metadata

Metadata

Assignees

Labels

📃 Docs문서 작성 및 수정 (README.md 등)

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions