Folders and files Name Name Last commit message
Last commit date
parent directory
View all files
설명
서버 기능
아키텍처
주요 구현 기능
피드백
트러블 슈팅
Game Matching API 서버로써, ASP.NET Core 8로 제작되었습니다.
매치 메이킹을 담당하는 서버로써, Game API 서버와 Game Socket 서버와 통신을 합니다.
멀티 스레드를 사용하고 있으며, 각 스레드의 기능은 다음과 같습니다.
API 요청 스레드들 : API 요청을 처리하며, 매칭 입장, 퇴장, 체크 등을 처리합니다.
매칭 처리 스레드 : 단일 스레드로, 매칭 입장이 된 유저들을 확인하여 게임 서버에게 매칭 처리 시도를 해주는 스레드입니다.
매칭 완료 처리 스레드 : 단일 스레드로, 게임 서버로 매칭 처리 시도가 완료된 요청들을 처리하는 스레드입니다.
Match Worker 코드
종류
라이브러리
Framework
ASP.NET Core 8
Redis
CloudStructures
Logger
ZLogger
기능
완료 여부
매치 입장
완료
매칭 취소
완료
매칭 체크 기능
완료
Redis List 기능을 통해 게임 서버와의 통신을 구현하였습니다.
매칭의 경우, 여러 게임 서버가 존재한다고 가정하였고, Redis의 List를 Queue처럼 사용하여 제일 먼저 데이터를 가져간 게임 서버가 자신의 주소와 룸 Number를 유저에게 알려주는 방식으로 진행함.
레디스에 유저의 현재 상태(로비, 매칭, 게임 등)를 저장하였고, 매칭 요청에 대해서 다음과 같이 처리함.
매칭 요청 : 유저가 로비 상태일 경우, 매칭 List에 추가하도록 처리. 이 외에는 실패 처리
매칭 취소 : 유저가 매칭 상태일 경우, 매칭 List에서 삭제하도록 처리. 이 외에는 실패 처리
각 서버들끼리 직접적인 통신을 안하게 하는 것이 좋다.
실제 라이브 중에서 스케일 아웃이나 장애 대응 등에 문제가 없는 방식으로 해야 한다.
메시지 큐나, 레디스, 소켓 직접 연결, 또는 요청 응답 -> 소켓서버에세 요청 응답 등 어떻게 할 것인지에 방법이 다양하다.
유저가 어느 정도 기다려야 하는지에 따라서 구현 방법이 달라질 수 있다.
매칭 서버의 경우 기본적으로 2 + α 의 스레드들이 동작하며 매칭 List에 동시 접근을 하는 상황이 발생
따라서 스레드 동기화 문제를 해결해야하며, 해결하는 과정 속에서 성능을 위해 오버헤드가 최소한으로 발생하여야 함.
기존의 ConCurrent 자료형의 경우, 다음과 같은 문제가 발생
ConCurrentBag, ConCurrentQueue, ConCurrentStak : 추가는 가능하나, 특정 유저 정보를 삭제하는 것이 어려움.
ConCurrentDictionary : 추가 및 삭제에는 용이하나 순회하는 등의 기능을 사용하려면 오버헤드가 많이 발생함.
ConCurrentList 를 따로 만들어서, 추가, 삭제, 첫 번째 데이터 꺼내기에만 Lock을 사용하여 Lock 사용 비용을 최소화할 수 있도록 만듬.
유저의 매칭 정보를 게임 서버와 주고 받기 위해서 통신이 필요함.
다만, 실장님께서 실제 라이브 중에서 문제가 없는 방식으로 해야 하며, 스케일 아웃이나 장애 대응을 고려해야한다고 말씀해주심.
직접 IP를 통해 통신하는 경우 서버가 스케일 아웃을 하거나, 장애 대응이 어렵다고 생각되어, Redis의 Pub/Sub이나 List 를 고려.
Redis의 Pub/Sub 의 경우 테스트 해본 결과 다음과 같은 문제가 발생.
Subscribe한 모든 서버에 데이터가 전송되기에 제일 먼저 받은 게임 서버가 처리하도록 하는 로직과는 다른 방식.
SubScribe하는 서버가 없다면 데이터가 저장되지 않는 문제.
따라서 Redis의 List 방식으로 수정하였고, List를 Queue처럼 사용하여 매칭 로직을 성공적으로 구현할 수 있었음.
You can’t perform that action at this time.