ACI(Azure Container Instances)를 사용하는 동기 멀티 플레이어

필요 시 자동으로 크기를 조정하고 사용 요금이 초당 부과되는 Azure Container Instances, Event Grid 및 Azure Functions를 사용하는 이 대체 솔루션에 대해 알아봅니다. 더 간단한 아키텍처 및 유지 관리가 필요할 경우 프리미엄 비용을 지불하면서 호스트된 가상 컴퓨터를 활용합니다.

서버 상태는 Azure Container Instances 외부에서 지속적이어야 합니다.

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

아키텍처 다이어그램

SAzure Container Instances를 사용하는 동기 멀티 플레이어

관련 서비스

  • Azure Traffic Manager - 대기 시간을 기준으로 플레이어를 가장 적절한 지역 영역에 연결하기 때문에 선택했습니다.
  • Azure Container Instances - 가상 컴퓨터를 관리할 필요가 없고 보다 고수준 서비스를 채택할 필요 없이 Azure에서 컨테이너를 실행 하는 가장 빠르고 간단한 방법입니다.
  • Azure 함수 - 소규모 논리를 실행하는 가장 간단한 방법이기 때문에 선택했습니다.
  • Azure 테이블 스토리지 - 컨테이너 그룹 상태를 추적하기 위한 간단한 키/특성 저장소입니다.
  • Azure Event Grid - Azure 서비스에서 발생하는 이벤트에 대한 지원을 기본 제공하기 때문에 선택했습니다.
  • Azure Blob Storage - 자동 크기 조정 도우미의 구성을 저장할 장소가 필요합니다.
  • 리소스 그룹 - Azure Traffic Manager용 리소스 그룹 1개와 각 지역 게임 서버 풀용 리소스 그룹 1개(예: 북아메리카용 1개, 유럽용 1개, LATAM용 1개, 아시아용 1개 등)를 활용합니다.

배포 템플릿

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

Deploy using an Azure Resource Manager template

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

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

프로젝트를 배포하려면 다음 정보를 지정해야 합니다.

  • 위치: 리소스를 배포할 Azure 지역을 선택합니다. Azure Container Instances를 사용할 수 있는 위치를 선택해야 합니다.
  • 함수 이름: 함수 앱에 고유한 이름을 선택합니다. 이는 함수의 DNS를 결정하므로 신중하게 선택해야 합니다.
  • 리포지토리 URL: Azure 함수를 만들기 위해 가져올 파일이 들어 있는 리포지토리를 결정합니다. 기본값을 그대로 사용하거나 개발자의 값으로 전환할 수 있습니다.
  • 분기: 프로젝트의 GitHub 분기에 해당합니다.

Azure Functions는 무료 App Service 계획에 배포되어 있으며, 성능을 향상하기 위해 크기를 조정해야 할 수 있습니다.

프로젝트는 필요한 Azure Container Instances를 생성/삭제/수정하기 위해 관리되는 서비스 ID 그리고 Azure Functions와의 관계를 이용하여 Azure ARM API Management 서비스에 인증합니다. 배포 스크립트는 자동으로 함수 앱의 앱 ID를 만들지만, 컨테이너 인스턴스를 호스트할 리소스 그룹에 이 ID 권한을 부여해야 합니다. 그렇게 하려면:

  • Azure Portal을 방문합니다.
  • Azure Container Instances를 만들 리소스 그룹을 찾습니다(함수 앱이 호스트되는 리소스 그룹일 수 있음).
  • 액세스 제어(IAM) 를 선택합니다.
  • 추가를 선택하고, 역할로 참가자를 선택하고, 함수 앱에 대한 액세스를 할당한 다음 구독/리소스 그룹 드롭다운 상자를 수정하여 Azure 함수를 선택합니다.
  • 저장을 클릭하면 모두 끝난 것입니다!

또한 배포가 완료되는 즉시 여기에 설명된 지침에 따라 ACIMonitor 함수에 대한 이벤트 구독 Webhook을 수동으로 추가해야 합니다. 이벤트를 모니터링할 올바른 리소스 그룹(즉, 컨테이너가 생성될 Azure 리소스 그룹)을 선택했는지 확인해야 합니다. 이렇게 하면 지정된 리소스 그룹에 리소스 수정이 발생하는 즉시 Event Grid가 ACIMonitor 함수에 메시지를 보내도록 할 수 있습니다. 이 작업이 완료되면 배포가 준비된 것입니다. 선택적으로, ACIMonitor함수의 URL을 가져오는 즉시 ARM 템플릿을 사용하여 Event Grid 구독을 배포할 수 있습니다.

Portal을 사용하여 Event Grid 구독을 배포하는 경우 다음 값을 입력해야 합니다.

  • 이름 - Event Grid 구독에 대한 고유한 이름을 선택합니다.
  • 토픽 유형 - '리소스 그룹'(또는 Azure Container Instances를 다양한 리소스 그룹에 배포할 경우 'Azure 구독')을 선택합니다.
  • 구독 - Azure Container Instances 만들기를 모니터링할 구독입니다.
  • 리소스 그룹 - 개발자가 만든 Azure 컨테이너 인스턴스를 포함할 리소스 그룹을 선택합니다. 모든 이벤트 유형 구독 확인란이 선택되어 있는지 확인합니다.
  • 구독자 유형 - Webhook.
  • 구독 엔드포인트 - ACIMonitorAzure 함수의 트리거 URL이 포함됩니다.
  • 접두사 필터 - 비워 둡니다.
  • 접미사 필터 - 역시 비워 둡니다.

마지막으로(하지만 이에 국한되지 않음) Azure Functions의 새로운 v2 런타임에 EventGrid 바인딩 확장을 수동으로 등록해야 할 수 있습니다. 일반적인 상황에서는 확장이 자동으로 설치됩니다(extensions.csproj 파일에 등록됨). 하지만 자동으로 설치되지 않을 경우 다음 문서를 참조하여 수동으로 설치할 수 있습니다.

단계별 설명

  1. 플레이어의 디바이스 클라이언트는 트래픽 관리자에 연결하여 게임 서버를 찾는 플레이어의 요청을 라우팅합니다.
  2. 트래픽 관리자는 대기 시간이 가장 짧은 지역 영역에 연결하고 매치 메이커를 가리켜 사용 가능한 게임 서버를 가져옵니다.
  3. 매치 메이커는 ACIList Azure 함수를 호출하여 모든 컨테이너 그룹에서 공용 IP 및 활성 세션의 목록을 가져옵니다.
  4. 이 Azure 함수는 Azure 테이블 저장소에서 모든 컨테이너 그룹의 공용 IP, 활성 세션 수 및 상태를 저장하는 테이블을 가져옵니다.
  5. 사용할 수 있는 항목이 없는 경우 ACICreate Azure 함수가 호출됩니다. 컨테이너 상태는 만드는 중입니다.
  6. ACICreate Azure 함수는 컨테이너를 만듭니다.
  7. Event Grid는 컨테이너가 만들어지거나 삭제될 때 수신 대기하도록 연결됩니다. 얼마 후(몇 분) Event Grid는 만들어지는 컨테이너에서 관련 이벤트를 수신합니다.
  8. 또한 Event Grid는 이벤트를 수신한 후 ACIMonitorAzure 함수를 호출하고 공용 IP를 전달하도록 설정됩니다.
  9. ACIMonitor Azure 함수는 새로 만든 컨테이너의 공용 IP를 삽입하고 컨테이너의 상태를 실행 중으로 설정합니다.
  10. 이제 매치 메이커는 플레이어가 사용할 수 있는 서버의 세부 정보를 디바이스 클라이언트로 다시 전송합니다. 그러면 디바이스 클라이언트가 서버에 직접 연결할 수 있습니다.
  11. 매치 메이커는 ACISetSession Azure 함수를 호출하여 플레이어가 지정된 컨테이너에서 실행 중인 활성 세션 수를 업데이트합니다.
  12. ACISetSession 함수는 Azure 테이블 저장소를 업데이트합니다.
  13. 일부 시점에서는 서버가 더 이상 필요하지 않습니다. 컨테이너 인스턴스는 계속 사용하는 플레이어가 있을 수 있기 때문에 수동으로 삭제할 수 없습니다. 그래서 서버를 종료하는 대신 ACISetState Azure 함수가 호출되어 컨테이너 상태를 MarkedForDeletion으로 설정합니다. 이제 이 컨테이너 인스턴스에는 새로운 사용자가 예약되지 않습니다.
  14. ACISetState Azure 함수는 Azure 테이블 저장소를 업데이트합니다.
  15. 시간 트리거 ACIGC Azure 함수가 수시로 실행되어 상태가 MarkedForDeletion인 컨테이너 인스턴스를 모두 삭제합니다.
  16. ACIGC Azure 함수는 실제로 컨테이너 인스턴스를 삭제하는 ACIDelete Azure 함수를 호출합니다.
  17. ACIDelete Azure 함수는 컨테이너를 삭제합니다.

보다 구체적인 예:

Azure 컨테이너 인스턴스 워크플로

  1. 시작할 때는 서버 인스턴스가 없습니다.
  2. 갑자기 플레이어가 연결할 서버가 필요해집니다. ACICreate 가 호출됩니다.
  3. 만들기 명령이 실행되지만 아직 서버는 실행되지 않습니다. 상태는 만드는 중입니다.
  4. 배포가 완료되면(몇 분) Event Grid에서 ACIMonitor를 통해 서버 인스턴스(컨테이너 그룹 1)가 특정 IP 주소(예: 1.2.3.4)에서 실행 중임을 알립니다. 인스턴스 상태가 실행 중으로 업데이트됩니다.
  5. 이제 플레이어가 서버 인스턴스에 연결할 수 있습니다.
  6. 이제 다른 서버 인스턴스가 필요하다고 가정합니다. 개발자는 ACICreate를 다시 사용할 수도 있고 확장 임계값이 초과된 경우 ACIAutoScaler가 개발자 대신 ACICreate를 사용하여 인스턴스를 만들도록 허용할 수도 있습니다.
  7. 다시 동일한 패턴으로 새 서버가 아직 준비되지 않습니다. 배포가 완료되면 Event Grid가 ACIMonitor를 통해 서버가 다른 특정 IP 주소(예: 2.3.4.5)에서 실행 중임을 알립니다. 이 두 번째 인스턴스(컨테이너 그룹 2)의 상태가 실행 중으로 업데이트됩니다.
  8. 이제 플레이어가 두 번째 인스턴스에 연결할 수 있습니다.
  9. 결국 개발자가 결정했거나 확장에 축소 임계값이 초과되었기 때문에 두 번째 인스턴스가 필요하지 않게 됩니다. 두 번째 인스턴스를 계속 사용하는 플레이어가 있을 수 있으므로 인스턴스를 종료하는 대신 ACISetScale이 호출되어 서버를 삭제하도록 표시합니다. 이제 두 번째 인스턴스에 새 플레이어가 예약되지 않습니다. 이제 두 번째 인스턴스의 상태가 MarkedForDeletion입니다.
  10. 두 번째 인스턴스에서 플레이어가 플레이를 완료하면 가비지 수집기 ACIGB가 실행되고 ACIDelete를 트리거하여 두 번째 인스턴스를 완전히 제거합니다.

크기 조정

ACIAutoScaler Azure 함수 설치는 환경 변수(축소/확장 임계값, 최소/최대 인스턴스 및 휴지)를 통해 구성할 수 있습니다. autoscaler의 논리는 다음과 같습니다.

  • 시간 트리거되는 경우 1분마다 실행되며 기본적으로 사용하지 않도록 설정됩니다.
  • 부하는 연결된 플레이어 수 / 총 플레이어 용량입니다.
  • ("부하" > 80% 및 인스턴스 < 최대값)일 경우 ACICreate Azure 함수를 호출하여 새 인스턴스를 스핀업합니다. 이는 확장을 담당합니다.
  • ("부하" < 60% 및 인스턴스 > 최소값)일 경우 ACISetState Azure 함수를 호출하여 부하가 가장 작은 인스턴스에 MarkedForDeletion 상태를 설정합니다. 이는 축소를 담당합니다.
  • 확대/축소하는 데 휴지 기간 10분이 있습니다.

Azure Container Instances는 신속하게 확장됩니다. 몇 분이면 새 컨테이너를 사용할 준비가 끝납니다. 예를 들어 OpenArena를 실행할 새 Azure 컨테이너 인스턴스 30개를 확장하라는 요청이 전송된 후 플레이어가 연결할 수 있을 때까지 3분이 채 걸리지 않았습니다.

테스트를 위해 수동으로 컨테이너 집합 만들기

테스트용으로 다양한 컨테이너 인스턴스를 만들려는 경우 여기에서 제공하는 샘플을 사용할 수 있습니다. openarenaserver1을 만들고 있는 각 인스턴스에 대한 고유한 이름(openarenaserver1, openarenaserver2, openarenaserver3 등)으로 바꿉니다. 또한 리소스 그룹, 위치 및 저장소 이름/키도 바꿉니다.

추가 리소스 및 샘플

자세한 내용은 Build에서 녹화된 Azure Container Instances를 사용하여 멀티 플레이어 서버 크기 조정 세션을 참조하세요.

가격

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

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

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