카테고리 없음

최종 프로젝트 MAFI4 회고록

news0516 2025. 3. 18. 18:06

1. MAFI4 간단한 구현 정리

메인 페이지
- 룸 리스트로 연결되는 버튼, 간단한 게임, 페이지 관련 정보

게시판 페이지
- 글 CRUD, 댓글 CRUD, 좋아요(토글 기반) 기능 구현

상점 페이지
DB 내 상품 정보 조회, 구매 시 내 포인트 차감(아이템 효과 적용은 미완성)

랭킹 페이지
DB 내 유저 테이블 포인트 컬럼 조회(개선 필요)

마이 페이지
게임 전적, 내 글, 내 댓글, 유저 테이블 조회 및 업데이트

룸 리스트 페이지
레디스에서 현재 룸 조회

룸(게임 방) 페이지
게임 서버와 웹소켓을 통한 이벤트 발행 및 구독, 게임서버 내 게임 로직으로 게임 진행
유저간 소통을 채팅으로 구현하기로 결정하였고, 실시간으로 유저간 소통을 구현하기 위해 웹소켓 반영

관리자 페이지
유저 테이블의 isAdmin 컬럼으로 관리자 권한 확인(벤 적용은 관리자만 가능하기 때문에)
특정 유저 닉네임으로 검색 가능,
해당 유저의 글, 댓글 조회 및 삭제
커뮤니티 벤, 게임 벤 적용(스케쥴러를 통해 5분마다 유저테이블의 bandate를 확인하여 벤 상태 체크, 
벤 기간이 실시간보다 이전 시점이라면, 해당 컬럼 자동 눌 처리)

2. 트러블 슈팅

1. Redis Pub/Sub 환경에서 endGame 로직 중복 실행 문제
Why? (문제의 본질)
게임이 종료되는 시점에서 활용되는 
endGame 로직이 중복 실행되어 동일 데이터가 여러 번 DB에 저장되는 문제 발생
- 마피아 인원, 시민 인원을 모든 투표단계가 끝날때 마다 판단하여, 게임 결과를 내리기 위한 로직이 필요했습니다.
이 endGame 로직에서 위와 같은 문제가 발생하였습니다

✅✅중복 실행의 구체적인 원인 파악 필요!!!!
아마... 
Pub/Sub은 메시지가 한 번 발행되면, 이를 구독한 모든 인스턴스가 수신함.
만약 endGame 메시지를 여러 게임 서버가 동시에 구독하고 있다면, 여러 개의 서버가 동시에 처리하게 될 가능성이 있음

How? (해결 방법)
게임 서버에서 Lock을 활용하여 중복 실행 방지
gameResult:{gameId}, gameAchievements:{gameId} 키를 확인하여, 
이미 저장된 데이터가 있으면 추가 저장 차단

✅✅ 피드백 받았었는데 더 좋은 방법 있는지 파악 필요!!!!
Redis Streams, Kafka 등 메시지 큐를 사용한
>> Redis Pub/Sub은 메시지를 모든 구독자에게 전달하지만, 메시지 큐는 "하나의 소비자(Consumer)"만 실행하도록 제어 가능

What? (결과 및 효과)
endGame 로직이 한 번만 실행되도록 보장하여 데이터 중복 저장 문제 해결
게임 결과의 무결성이 유지되고, DB 부하 감소

최종 정리!!
마피아 게임에서 투표가 종료될 때마다 남은 마피아와 시민 인원을 판단하여 게임 결과를 결정하는 endGame 로직이 필요했습니다.
하지만 Redis Pub/Sub 환경에서 endGame 메시지가 모든 게임 서버 인스턴스에 전파되면서, 
동일한 게임 결과가 여러 번 저장되는 중복 실행 문제가 발생하였습니다.

이 문제를 해결하기 위해 **Redis 분산 락(Redis Lock)**을 적용하여 하나의 서버에서만 endGame이 실행되도록 제한하였고,
추가적으로 캐시(gameResult:{gameId}, gameAchievements:{gameId})를 활용하여, 이미 처리된 요청인지 확인하는 로직을 추가하였습니다.

이러한 개선을 통해 데이터 중복 저장을 방지할 뿐만 아니라, 게임 결과의 무결성을 유지하고, DB 부하를 줄이는 효과를 얻었습니다.
결과적으로 게임 로직의 안정성이 향상되고, 중복 실행으로 인한 리소스 낭비가 최소화되었습니다

2. 서버 부하 분산 문제 해결
Why? (문제의 본질)
Redis와 API 서버를 각각 단일 서버로 분리
게임 서버는 ECS(AWS Elastic Container Service)로 구성하여 확장 가능하도록 개선
ALB(AWS Application Load Balancer) 도입하여 부하를 자동으로 분산

How? (해결 방법)
Redis와 API 서버를 각각 단일 서버로 분리
게임 서버는 ECS(AWS Elastic Container Service)로 구성하여 확장 가능하도록 개선
ALB(AWS Application Load Balancer) 도입하여 부하를 자동으로 분산

What? (결과 및 효과)
서버의 확장성과 성능이 최적화됨
부하가 증가해도 안정적인 서비스 운영 가능
트래픽 증가에도 대응할 수 있는 구조로 개선됨


3. MAFI4 프로젝트 피드백


1. 반응형 웹으로 디자인
>> 모바일 환경에 적절해보이는 주제로 판단되어 반응형 웹으로 디자인하는 것이 적절했을 수 있다.

2. 대규모 서비스에 대비
>> 현재는 여러 API들이 db를 직접 조회하는 형태로 구성되어, 대규모 서비스일 경우에 대한 부하 데스트와 대비가 필요. >> 캐시 데이터 사용 고려

3. 유저 테이블에서 재화, 게임포인트 등을 컬럼으로 관리
>> 유저 재화, 게임 포인트 등 민감한 정보는 따로 테이블을 구성하고 트랜잭션을 통한 일관성 보장, 버그 방지 필요

4. 굳이 ALB를 통한 분산이 필요한가?
>> 근본적인 파악 후 아키텍쳐 수정 필요

 

5. 현재 처럼 게임 서버 주소를 그때 그때 저장하고 찾아가는 로직이 굳이 필요한가?
자동으로 증가하고 감소하는 도커 컨테이너 기반 게임 서버의 주소가 계속 바뀌면서, 이를 찾기 위해 별도의 로직이 필요했기 때문에, 현재처럼 방 정보에 저장된 게임서버주소를 특정하기 위한 로직이 필요했음
>> Redis를 활용한 "방-컨테이너 매핑"
방 생성 시 컨테이너를 Redis에 저장하여 해당 방 유저들이 같은 컨테이너를 사용하도록 지정 가능

6. 같은 방 내 유저들이 동일한 게임서버를 사용하도록 하는 이유
>> 우리가 생각한 이유로는..
마피아 게임(채팅, 턴제 기반)에서는 같은 방의 유저가 동일한 게임 서버를 사용하도록 한 설계가 필수적이라고 단언하기는 어렵고, 실시간 FPS, MOBA 같은 게임에 비해서는 동기화가 덜 중요하다고 볼 수도 있다
하지만 게임의 안정성, 동기화 일관성 유지 측면에서 적절한 선택이라고 생각.
이론적으로는 다른 서버라도 채팅, 투표, 게임 상태의 일관성을 유지할 수 는 있지만, 추가적인 동기화 로직과 네트워크 지연 측면에서 어렵고, 복잡성이 증가하고, 덜 안정적인 방법이라고 판단 (추가적인 동기화 로직 > 분산 메시징 시스템 사용 (Kafka, Redis Pub/Sub) , 중앙 데이터베이스 (DB) 활용 등 )

7. 수치/정량화 된 성과 표시를 위한 테스트 진행 필요
>> 부하 테스트, 스트레스 테스트 방법 고안 후 적용해 데이터 도출 필요(이력서에 필요)

추가, 수정 예정