Skip to content

Latest commit

 

History

History

MatchMackingServer

MatchMaking Server

목차

  1. 설명
  2. 서버 기능
  3. 아키텍처
  4. 주요 구현 기능
  5. 피드백
  6. 트러블 슈팅

설명

  • Game Matching API 서버로써, ASP.NET Core 8로 제작되었습니다.
  • 매치 메이킹을 담당하는 서버로써, Game API 서버와 Game Socket 서버와 통신을 합니다.
  • 멀티 스레드를 사용하고 있으며, 각 스레드의 기능은 다음과 같습니다.
    • API 요청 스레드들 : API 요청을 처리하며, 매칭 입장, 퇴장, 체크 등을 처리합니다.
    • 매칭 처리 스레드 : 단일 스레드로, 매칭 입장이 된 유저들을 확인하여 게임 서버에게 매칭 처리 시도를 해주는 스레드입니다.
    • 매칭 완료 처리 스레드 : 단일 스레드로, 게임 서버로 매칭 처리 시도가 완료된 요청들을 처리하는 스레드입니다.
  • Match Worker 코드
종류 라이브러리
Framework ASP.NET Core 8
Redis CloudStructures
Logger ZLogger

서버 기능

매칭 관련

기능 완료 여부
매치 입장 완료
매칭 취소 완료
매칭 체크 기능 완료

아키텍처

alt text

주요 구현 기능

매칭 기능 구현

  • Redis List 기능을 통해 게임 서버와의 통신을 구현하였습니다.
  • 매칭의 경우, 여러 게임 서버가 존재한다고 가정하였고, Redis의 List를 Queue처럼 사용하여 제일 먼저 데이터를 가져간 게임 서버가 자신의 주소와 룸 Number를 유저에게 알려주는 방식으로 진행함.
  • 레디스에 유저의 현재 상태(로비, 매칭, 게임 등)를 저장하였고, 매칭 요청에 대해서 다음과 같이 처리함.
    • 매칭 요청 : 유저가 로비 상태일 경우, 매칭 List에 추가하도록 처리. 이 외에는 실패 처리
    • 매칭 취소 : 유저가 매칭 상태일 경우, 매칭 List에서 삭제하도록 처리. 이 외에는 실패 처리

피드백

  1. 각 서버들끼리 직접적인 통신을 안하게 하는 것이 좋다.
  2. 실제 라이브 중에서 스케일 아웃이나 장애 대응 등에 문제가 없는 방식으로 해야 한다.
  3. 메시지 큐나, 레디스, 소켓 직접 연결, 또는 요청 응답 -> 소켓서버에세 요청 응답 등 어떻게 할 것인지에 방법이 다양하다.
    • 유저가 어느 정도 기다려야 하는지에 따라서 구현 방법이 달라질 수 있다.

트러블 슈팅

스레드 동기화 문제

  • 매칭 서버의 경우 기본적으로 2 + α 의 스레드들이 동작하며 매칭 List에 동시 접근을 하는 상황이 발생
  • 따라서 스레드 동기화 문제를 해결해야하며, 해결하는 과정 속에서 성능을 위해 오버헤드가 최소한으로 발생하여야 함.
  • 기존의 ConCurrent 자료형의 경우, 다음과 같은 문제가 발생
    • ConCurrentBag, ConCurrentQueue, ConCurrentStak : 추가는 가능하나, 특정 유저 정보를 삭제하는 것이 어려움.
    • ConCurrentDictionary : 추가 및 삭제에는 용이하나 순회하는 등의 기능을 사용하려면 오버헤드가 많이 발생함.
  • ConCurrentList를 따로 만들어서, 추가, 삭제, 첫 번째 데이터 꺼내기에만 Lock을 사용하여 Lock 사용 비용을 최소화할 수 있도록 만듬.

게임 서버와의 통신

  • 유저의 매칭 정보를 게임 서버와 주고 받기 위해서 통신이 필요함.
  • 다만, 실장님께서 실제 라이브 중에서 문제가 없는 방식으로 해야 하며, 스케일 아웃이나 장애 대응을 고려해야한다고 말씀해주심.
  • 직접 IP를 통해 통신하는 경우 서버가 스케일 아웃을 하거나, 장애 대응이 어렵다고 생각되어, Redis의 Pub/Sub이나 List를 고려.
  • Redis의 Pub/Sub의 경우 테스트 해본 결과 다음과 같은 문제가 발생.
    • Subscribe한 모든 서버에 데이터가 전송되기에 제일 먼저 받은 게임 서버가 처리하도록 하는 로직과는 다른 방식.
    • SubScribe하는 서버가 없다면 데이터가 저장되지 않는 문제.
  • 따라서 Redis의 List 방식으로 수정하였고, List를 Queue처럼 사용하여 매칭 로직을 성공적으로 구현할 수 있었음.