DungeonTalk 백엔드 개발기 - 1편: 멀티 데이터베이스 아키텍처 설계

MJ·2025년 8월 14일
post-thumbnail

실시간 AI 게임 채팅 플랫폼을 구축하며 마주한 아키텍처 설계 고민들

프로젝트 개요

DungeonTalk은 AI와 함께하는 실시간 던전 게임 채팅 플랫폼입니다. 사용자들이 AI GM과 함께 텍스트 기반 RPG를 즐길 수 있는 멀티플레이어 환경을 제공합니다.

주요 기능

  • AI 채팅: AI GM과의 실시간 던전 게임
  • 일반 채팅: 유저 간 자유 채팅
  • 매칭 시스템: 게임 룸 자동 매칭
  • 통합 룸: 채팅룸과 AI룸 통합 관리

아키텍처 결정 배경

왜 멀티 데이터베이스를 선택했을까?

초기에는 단일 데이터베이스로 시작하려 했지만, 각 도메인의 데이터 특성을 분석하며 다른 결론에 도달했습니다.

 사용자/인증 데이터 (PostgreSQL)
   └─ 강한 일관성, 트랜잭션 보장, 정규화

 채팅 메시지 (MongoDB) 
   └─ 대량 읽기/쓰기, 스키마 유연성, 로그 성격

 세션/캐시 (Redis)
   └─ 실시간 상태 관리, Pub/Sub, 휘발성

기술 스택 선택 과정

Backend Framework

Spring Boot 3.4 + Java 21을 선택한 이유:

  • Virtual Threads: 대량 동시 연결 처리에 유리
  • 성숙한 생태계: WebSocket, Security, JPA 통합
  • 팀 익숙도: 빠른 개발 속도

데이터베이스 전략

1️⃣ PostgreSQL (관계형 데이터)

@Entity
public class Member extends BaseEntity {
    @Id private String id;
    @Column(unique = true) private String username;
}

선택 이유: 사용자, 인증 데이터는 ACID 트랜잭션이 중요

2️⃣ MongoDB (문서형 데이터)

@Document(collection = "ai_game_messages")
public class AiGameMessage {
    @Id private String id;
    private String roomId;
    private String content;
    @Indexed private Integer messageOrder;
}

선택 이유: 채팅 메시지는 스키마 유연성대량 처리가 우선

3️⃣ Redis/Valkey (캐시 & 세션)

이중 Redis 구성을 통한 역할 분리:

  • Session Redis: 사용자 세션, JWT 토큰 관리
  • Cache Redis: 게임 상태, 매칭 큐, Pub/Sub

실시간 통신 아키텍처

WebSocket + STOMP 설계

@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig {
    public void configureMessageBroker(MessageBrokerRegistry registry) {
        registry.enableSimpleBroker("/sub");
        registry.setApplicationDestinationPrefixes("/pub");
    }
}

핵심 설계 원칙:

  • JWT 기반 인증: HandshakeInterceptor에서 토큰 검증
  • 채널 분리: 도메인별 독립적인 메시지 채널
  • SockJS Fallback: 다양한 브라우저 환경 지원

메시지 플로우 설계

Client → WebSocket STOMP → Spring Boot → MongoDB (저장)
                              ↓
                           Redis Pub/Sub → All Connected Clients

보안 아키텍처

JWT + Spring Security

이중 인증 구조:
1. REST API: JWT Filter Chain
2. WebSocket: Handshake Interceptor

성능 최적화 전략

1. 비동기 처리

  • 매칭 시스템: 전용 스레드 풀로 비동기 처리
  • AI 응답: 논블로킹 HTTP 클라이언트 사용

2. MongoDB 인덱싱 전략

  • 복합 인덱스: roomId + messageOrder로 메시지 조회 최적화
  • 자동 인덱스 생성: 애플리케이션 시작 시 인덱스 확인

3. Redis TTL 관리

  • 세션 TTL: 1시간 (3600초)
  • 매칭 상태 TTL: 1시간
  • 사용자 정보 TTL: 7일

도메인 분리 전략

패키지 구조

src/main/java/org/com/dungeontalk/domain/
├── aichat/     - AI 채팅 게임 (내가 담당)
├── matching/   - 게임 매칭 시스템 (내가 담당)  
├── room/       - 통합 룸 관리 (내가 담당)
├── chat/       - 일반 채팅
├── auth/       - 인증/인가
└── member/     - 사용자 관리

설계 패턴 적용:

  • Factory Pattern: RoomServiceFactory, MatchingRoomFactory
  • Adapter Pattern: AiGameRoomServiceAdapter, ChatRoomServiceAdapter
  • Builder Pattern: 모든 DTO/Entity (Lombok 활용)

개발 환경 구성

프로파일별 설정 관리

  • 환경변수 기반: .env 파일로 민감 정보 분리
  • 프로파일 분리: dev, test, prod 환경별 설정

테스트 전략

  • Testcontainers: 실제 데이터베이스로 통합 테스트
  • H2 Database: JPA 유닛 테스트용 인메모리 DB

앞으로의 계획

다음 편에서는 AI 채팅 시스템의 구체적인 구현을 다룰 예정입니다:

  • WebSocket 실시간 메시징 구현
  • AI API 연동 및 비동기 처리
  • 게임 상태 관리 (페이즈, 턴 시스템)
  • Redis Pub/Sub 활용한 실시간 알림

시리즈 목차
1. 멀티 데이터베이스 아키텍처 설계 ← 현재
2. AI 채팅 시스템 구현 (aichat)
3. 실시간 매칭 시스템 구현 (matching)
4. 통합 룸 시스템 구현 (room)
5. 개발 회고 & 성능 최적화

profile
..

0개의 댓글