멀티 플레이어 서버리스 매치 메이커

이 문서에서는 GitHub의 이 샘플에 사용된 아키텍처에 대해 설명합니다. 이 참조 아키텍처의 코드는 지침을 위한 예제일 뿐이며 프로덕션 환경에서 사용하기 위해서는 일부 코드를 최적화해야 할 수 있습니다.

MAzure Cache for Redis 및 Azure Functions를 사용하는 매치 메이커

관련 서비스

  • Azure Traffic Manager - 대기 시간을 기준으로 플레이어를 가장 적절한 지역 영역에 연결하기 때문에 선택했습니다.
  • Azure 함수 - 매치 메이킹 논리의 작은 부분을 실행하는 가장 간단한 방법이며 매치 메이킹 및 플레이를 시도하는 사용자가 있는 경우에만 요금이 부과되기 때문에 선택했습니다.
  • Azure 이벤트 허브 - 일괄 처리 요청을 허용하며, Azure Cache of Redis 연결 풀 소진을 방지하는 데 유용합니다.
  • Azure Cache for Redis - 멀티 플레이어 세션에 참가하려는 각 플레이어의 정보, 그리고 사용되는 게임 서버의 연결 정보(IP/포트)를 저장하기 위한 단순한 키/값 쌍 데이터베이스입니다. 쿼리 유연성, 인덱싱, 복제 때문에 선택했으며, 데이터 이동이 엄격한 요구 사항이 아니고 가격 책정도 저장 용량만을 기준으로 합니다.
  • 리소스 그룹 - Azure Traffic Manager용 리소스 그룹 1개와 각 매치 메이킹 지역 처리기용 리소스 그룹 1개(예: 북아메리카용 1개, 유럽용 1개, LATAM용 1개, 아시아용 1개 등)를 활용합니다.

배포 템플릿

다음 단추를 클릭하여 프로젝트를 Azure 구독에 배포합니다.

이 작업은 Azure 구독에 대한 azuredeploy.json ARM 템플릿 파일의 템플릿 배포를 트리거합니다. 그러면 필요한 Azure 리소스가 만들어집니다. 이로 인해 Azure 계정에 요금이 부과될 수 있습니다.

Azure 서비스에 대한 명명 규칙 및 제한 사항을 요약하는 섹션이 포함된 일반 지침 문서를 참조하세요.

참고

ARM 템플릿이 작동하는 방식에 관심이 있는 경우 이 참조 아키텍처에 활용된 각 서비스에서 Azure Resource Manager 템플릿 설명서를 참조하세요.

마지막으로, 샘플 프로젝트에서 Azure 서비스에 연결할 수 있도록 함수 애플리케이션 설정을 추가합니다.

  • EVENTHUB_CONNECTION_STRING - 만들어진 Azure 이벤트 허브 네임스페이스에 대한 연결 문자열입니다.
  • REDIS_CONNECTION_STRING - 만들어진 Azure Cache for Redis에 대한 연결 문자열입니다.

Azure Functions를 로컬로 실행하려면 다음과 동일한 앱 설정을 사용하여 local.settings.json 파일을 업데이트합니다.

단계별 설명

  1. 플레이어의 디바이스 클라이언트는 트래픽 관리자에 연결하여 플레이어를 매치 메이킹 대기열에 추가하라는 요청을 라우팅합니다.
  2. 트래픽 관리자는 대기 시간이 가장 짧은 지역 영역에 연결하고 요청을 캡처하여 일괄 처리하도록 허용하는 Azure 이벤트 허브를 가리킵니다.
  3. 이벤트 허브는 매치 메이킹 풀에 추가될 새 플레이어의 세부 정보를 add players Azure 함수에 전달합니다.
  4. 이 Azure 함수는 먼저 폴링 메커니즘을 통해 플레이어에게 게임 서버 연결 세부 정보를 제공할 엔드포인트를 노출하는 match request 지속성 Azure 함수 오케스트레이터를 만듭니다. 매치 메이킹당 하나의 오케스트레이터가 있으며, 나중에 이벤트를 보낼 수 있으려면 오케스트레이터의 오케스트레이션 인스턴스 ID가 플레이어의 GUID여야 합니다.
  5. 그런 다음 동일한 Azure 함수는 데이터베이스에 플레이어를 추가하고 적합한 기존 게임 세션에 이를 포함시킵니다. 사용 가능한 게임 세션이 없을 경우 하나를 만듭니다.
  6. 이후 폴링 메커니즘에서 플레이어의 디바이스 클라이언트가 트래픽 관리자에 연결하여 플레이어에게 게임 세션 연결 세부 정보를 제공하라는 요청을 라우팅합니다.
  7. 트래픽 관리자는 앞서(4단계) 언급한 Azure 함수를 가리킵니다.
  8. 이 Azure 함수는 시간 제한용 타이머를 만든 다음 게임 세션 서버 연결 세부 정보(IP:포트)를 포함하는 이벤트 또는 시간 초과 이벤트 중 먼저 도래하는 이벤트를 대기합니다.
  9. ready session 타이머 트리거 Azure 함수가 데이터베이스를 스캔하여 매치를 시작하기에 충분한 플레이어가 있는 모든 세션을 가져옵니다.
  10. 또한 데이터베이스에서 사용 가능한 서버를 찾아 서버 연결 세부 정보(IP:포트)를 가져오고 해당 서버를 사용 가능한 서버 목록에서 제거합니다.
  11. 시작할 준비가 된 각 게임 세션에 대해 ready session 타이머 트리거 Azure 함수는 플레이어 목록을 가져오고 이 정보를 서버 연결 세부 정보와 함께 Azure 이벤트 허브에 전달합니다.
  12. 이 Azure 이벤트 허브는 *match made notification distributor Azure 함수를 생성합니다.
  13. 이 Azure 함수는 Azure 이벤트 허브 메시지를 사용하고, 플레이어 GUID를 오케스트레이터 인스턴스 ID로 이용하여 각 플레이어의 match request 지속성 Azure 함수 오케스트레이터(단계 6)에 연결합니다.
  14. 디바이스 클라이언트는 연결할 서버 연결 세부 정보(IP:포트)를 수신하고 게임 서버에 직접 연결합니다. 매치 메이킹 시도에서 시간 초과가 발생하는 경우 디바이스 클라이언트는 이를 정상적으로 처리합니다.

구현 세부 정보

매치 요청 모니터 (매치 요청당 하나)

플레이어가 게임에 연결하려는 경우 다음을 수행하는 Match Request 지속성 Azure 함수 오케스트레이터를 시작합니다.

  1. 요청의 시간 제한 기간 동안 CreateTimer를 호출합니다.
  2. WaitForExternalEvent를 호출하여 서버 정보를 포함하는 서버 준비 이벤트가 발생하기를 기다립니다(Match Made Notification Distributor Azure 함수 참조).
  3. 작업 사용.첫 번째 작업이 1 또는 2를 반환할 때까지 기다립니다.
  4. 서버 준비 이벤트가 도착하기 전에 시간 초과가 발생하는 경우 디바이스 클라이언트에서 인식하는 일종의 오류 메시지를 반환합니다.
  5. 서버 준비 이벤트가 시간 초과 전에 도착하는 경우:
    • 시간 제한 타이머를 취소합니다.
    • 서버 정보를 반환합니다.

참고: 게임의 오케스트레이션 인스턴스 ID는 플레이어 ID이거나 a) 디바이스 클라이언트가 보유하고 b) Azure Cache for Redis에 저장된 요청의 기타 고유한 식별자여야 합니다.

일괄 처리된 준비 세션 모니터(타이머 트리거 Azure 함수)

Azure 함수 앱의 시작 시 시작됩니다.

  1. 모든 준비 세션에 대해 Azure Cache for Redis를 쿼리합니다.
  2. 각 준비 세션에 대해 서버 준비 알림을 보냅니다.

Match Made Notification Distributor Azure 함수

'서버 준비' 알림을 사용하는 notification 시스템 트리거 Azure 함수(지속성 아님)에서:

  1. Match Made Notification Distributor Azure 함수로 요청을 전송합니다.
  2. Match Request 지속성 Azure 함수 오케스트레이터를 사용하여 세션의 각 플레이어에게 서버 준비 이벤트를 전송합니다.
    • 플레이어 ID와 일치하는 오케스트레이터 인스턴스 ID로 보내기 - 특정 오케스트레이션 인스턴스 ID를 사용하여 이 함수가 이벤트를 전송할 위치를 인식하는 방식입니다.
    • 서버 정보를 전송합니다.

디바이스 클라이언트는 매치 요청 모니터의 상태를 폴링하여 오케스트레이션이 진행 중인지 a) 시간 초과 메시지 또는 b) 서버 정보와 함께 완료되었는지 확인합니다. b인 경우 서버에 연결합니다. 특히 이 시나리오의 경우 디바이스 클라이언트에서 호출해야 하는 GET URL은 다음과 같습니다. GET /runtime/webhooks/durabletask/instances/{playerGUID}?code={systemKey}

독자를 위한 연습

제공된 샘플에는 플레이어가 진행 중인 매치 메이킹 요청을 취소하기로 결정한 경우 처리할 논리가 포함되어 있지 않습니다. 이 시나리오에서는 이후 매치 메이킹 시도를 가능하게 하기 위해 플레이어를 데이터베이스에서 제거해야 합니다.

PlayersTimeStartedMatchmaking 및 SessionsCreationTime 정렬된 집합을 사용하지 않습니다. 이들 집합은 매치 메이킹 시간을 최적화하는 데 활용될 수 있습니다.

또한 최대한 일반적인 샘플을 만들기 위해 이 샘플에는 사용 가능한 서버가 없는 경우 확장 요청을 수행하는 코드가 포함되어 있지 않습니다. 일괄 처리된 준비 세션 모니터 타이머 트리거 Azure 함수 내에 큐가 있습니다.

데이터베이스 설정

이름 Redis 형식 세부 정보 Redis 명령 샘플
서버 Redis 해시 서버 정보를 저장합니다. hmset Servers GUID "IP:Port" GUID "IP:Port"
ServersAvailable Redis 집합 사용 가능하며 게임 세션을 호스트할 수 있는 서버 GUID를 저장합니다. sadd ServersAvailable "GUID"
플레이어 Redis 해시 플레이어 정보를 저장합니다. hmset Player:GUID Name "value1" MatchmakingSettings "value2"
PlayersTimeStartedMatchmaking Redis 정렬된 집합 플레이어가 매치를 찾기 시작한 날짜를 저장합니다. 키는 플레이어 GUID이고, 값은 날짜의 UNIX 타임스탬프입니다. zadd PlayersTimeStartedMatchmaking GUID TIMESTAMP
세션 Redis 해시 용량, 매치 메이킹 버킷 등 게임 세션 정보를 저장합니다. hmset Session:GUID Capacity value1 MatchmakingSettings value2
SessionsPerMatchmaking Redis 집합 매치 메이킹 버킷별 세션을 저장합니다. sadd SessionsPerMatchmaking:MatchmakingBucket "GUID"
SessionPlayers Redis 집합 게임 세션의 플레이어 식별자를 저장합니다. sadd SessionPlayers:SESSIONGUID "PLAYERGUID"
SessionsReady Redis 집합 용량이 0(즉, 게임 서버를 사용할 수 있는 즉시 시작할 수 있다는 의미)인 모든 세션을 저장합니다. sadd SessionsReady "GUID"
SessionsCreationTime Redis 정렬된 집합 각 게임 세션이 초기화된 날짜를 저장합니다. zadd SessionsCreationTime GUID TIMESTAMP

크기 조정

Azure Cache for Redis 용량 측면에서 매치 메이킹 정보를 저장하는 데이터베이스를 적절하게 크기 조정하는 방법을 알아보려면 Azure Cache for Redis 크기 조정 방법을 참조하세요.

Azure 이벤트 허브 특징과 파티션 수를 모델링하기 위한 경험 법칙을 이해하려면 일반 지침 설명서를 참조하세요.

추가 리소스 및 샘플

Unity용 Azure Event Hubs SDK: 샌드박스 프로젝트입니다. 이 문서의 내용은 지원되지 않습니다. 따라서 최신 상태가 아니거나 작동 상태가 아닐 수 있습니다.

가격

Azure 구독이 없는 경우 무료 계정을 만들어 12개월 무료 서비스를 시작합니다. 이러한 서비스의 제한을 초과하지 않는 한 Azure 무료 계정에서 무료로 제공하는 서비스에 대해서는 요금이 부과되지 않습니다. Azure Portal을 통해 또는 사용량 파일을 통해 사용량을 확인하는 방법을 알아보세요.

이러한 참조 아키텍처를 실행하는 동안 사용되는 Azure 서비스의 비용은 사용자가 부담하며, 전체 비용은 분석 파이프라인을 통해 실행되는 이벤트 수에 따라 달라집니다. 참조 아키텍처에 사용된 각 서비스에 대한 가격 웹 페이지를 참조하세요.

Azure 가격 계산기를 사용하여 사용하려는 Azure 서비스에 대한 비용을 구성하고 예측할 수도 있습니다.