리릭잇 · 노래 가사 기반 실시간 게임

기간  — 

라운드마다 나오는 가사 키워드를 보고 채팅으로 노래를 맞히는 실시간 게임입니다. 크롤링하고 분산 처리한 역대 인기 가요 가사 데이터를 씁니다. 백엔드 작업 대부분을 맡았고, 서버와 CI/CD는 혼자 구축했습니다. Jenkins로 배포 시나리오를 여러 가지 구성했고, QA를 이어 가며 사용성을 다듬었습니다.

백엔드 리드로 실시간 채팅⁠·⁠게임 통신과 인프라 담당

Java 17Spring Boot 3.2.1Spring Data JPAWebSocket (STOMP)MySQL 8.0.35Redis 7.2AWS EC2JenkinsDocker

  • 실시간 방 정보 갱신과 채팅
  • 방 생성, 게임 준비⁠·⁠시작, 진행 방식 설정
  • 채팅으로 가장 먼저 정답을 맞힌 사람이 이기는 라운드
  • 가사 데이터 검색

페이지별 실시간 메시지 채널

문제
게임의 메시지 채널이 많아 리소스 부담과 채널 관리, 개발 비용을 함께 줄여야 했습니다. 컴포넌트별 채널과 페이지별 채널 중 하나를 골라야 했고, 개발 비용을 줄이려면 직관적인 방식이어야 했습니다.
해결
페이지마다 메시지 채널을 하나로 합쳤습니다. 응답 형식은 통일하고 메시지 종류로 상황을 나눠, 채널 관리 복잡도를 줄였습니다. 리소스 부담을 줄였고, 기능은 메시지 종류를 더하는 방식으로 늘렸습니다.

세션 끊김

문제
로그아웃이 아니라 소켓 세션 단절로 오프라인을 판단했고, Redis의 방⁠·⁠게임 상태도 함께 갱신해야 했습니다. 타임아웃으로 연결이 끊기는 문제도 있었습니다.
해결
인터셉터에서 STOMP 명령을 확인해 연결 상태별로 처리하고, 게임 중 한 명이 끊기면 그 게임과 방 데이터를 지우고 갱신했습니다. 채널 인터셉터는 이벤트 리스너로 처리를 넘겨 순환 참조를 피했습니다. heartbeat로 일정 간격마다 ping⁠·⁠pong 프레임을 주고받아 타임아웃 끊김을 막았습니다.

아키텍처

Nginx, Next.js, Spring Boot, Redis, MySQL, Elasticsearch, Kibana, Spark, Beautiful Soup을 보여 주는 리릭잇 배포 구조도
서비스 서버와 가사 검색⁠·⁠수집 구성을 나눈 구조입니다.
리릭잇 로고와 로그인 창이 보이는 시작 화면
로고와 로그인 창이 보이는 리릭잇 시작 화면
가사 게임 방 목록이 보이는 리릭잇 로비
가사 키워드와 순위가 표시된 리릭잇 게임 화면
참가자와 게임 설정이 보이는 리릭잇 대기실
노래 검색과 가사가 보이는 리릭잇 사전 화면