AWS 기반의 확장 가능한 게임 개발 패턴 소개 (SECOND EDITION)

HyeonKi Jo·2022년 3월 19일
0

AWS_Cloud

목록 보기
1/1

AWS 기반의 확장 가능한 게임 개발 패턴 소개 (SECOND EDITION)
Dhurv Thukral, Greg McConnel, Brent Nash, Jack Hamion, Keith Lafaso, Chris Blackwell


서론

  • 서버 백앤드
  1. 멀티플레잉, 채팅, 매치 메이킹 등의 게임 서비스를 구동하는 서버로 구성될 수 있다.
  2. 사용자가 급격히 늘어날 경우, 서버 백엔드를 즉시 확장할 수 있어야 한다.
  3. 백엔드는 사용되지 않는 서버 용량에 대해 초과 지불하지 않는 경제성을 제공해야 한다.
  • Amazon Web Services(AWS)
    AWS는 유연하고, 비용 효과적이며, 사용이 쉽다. 온디멘드 용량을 활용하여 사용자 수에 따라 확장 및 축소도 가능하다.


시작하기

게임 설계 의사 결정

  • 모든 위치에서 픽업 앤 플레이
    플레이어는 저장된 게임정보 및 개인 데이터를 온라인으로 저장해, 여러 디바이스 간에 손쉽게 이동할 수 있기를 바란다. 이 작업에는 디바이스를 이동할 때, 로컬 데이터를 동기화하고 병합하는 간계가 포함된다.
  • 리더보드 및 순위 지정
    플레이어는 경쟁환경을 찾는다. 그러나 기존의 글로벌 고득점 목록이 아닌, 친구의 리더보드로 초점이 이동하고 있다. 이때 양호한 성능을 유지하면서 여러 차원으로 정렬할 수 있는 보다 정교한 리더보드가 필요하다.
  • 무료플레이
    이 모델에서는 게임을 무료로 다운로드 및 플레이할 수 있다. 대신 무기, 옷, 부스트 등과 같은 앱 내 구매와 광고로 수익을 낸다. 이러한 모델에선 소수의 사용자가 게임에 자금을 대기 때문에 게임의 백엔드는 가능한 경제적이여야 하며 확장과 축소가 가능해야 한다.
  • 분석
    매출을 최대화 하기위해, 게임에서 플레이패턴, 즐겨찾는 아이템, 구매 선호도 등 많은 수의 지표를 수집하고 분석해야 한다.
  • 콘텐츠 업데이트
    상위권의 플레이어 유지율을 달성하는 게임은 아이템, 레벨, 도전과제등에서 연속적인 주기로 릴리즈 된다. 게임이 단일 제품보다 서비스에 가까워지며, 출시 후 꾸준이 변경해야 할 필요성이 더욱 커지고 있다. 이런 특징은 새로운 데이터와 게임 리소스를 자주 업데이트 할 것을 요구한다. CDN(콘텐츠 전송 네트워크)을 사용하여 게임 콘텐츠를 배포하면 비용절감 및 다운로드 속도 개선이 가능하다.
  • 비동기식 게임플레이
    포인트, 잠금풀기 등의 목표달성을 기반으로 친구와 경쟁하는 것이 포함된다. 온라인이 아니거나 느린 인터넷을 사용해도 게임에 연결되어 있는 느낌을 받을 수 있다.
  • 푸시알림
  • 예측 불가능한 클라이언트
    모바일 환경에서와 다른 콘솔 사용자와 게임에서 겨루는 경우, 두 사용자는 모두 같은 경험을 기대합니다. 이러한 이유로, 상태 비저장 프로토콜(예: HTTP)과 비동기식 호출을 가능한 많이 활용하는 것이 필요합니다.

이러한 각 게임 기능은 서버 기능과 기술에 영향을 미친다. 한 예로, 상위 10위 리더보드가 있을떄 단일 MySQL을 사용할 수 있지만 다수의 정렬 차원이 있는 복잡한 리더보드가 있는 경우에는, Amazon Elaticache 또는 Amazon DynamoDB같은 NoSQL기술을 사용해야 합니다.

게임 클라이언트 고려사항

  • 모든 네트워크 호출은 비동기식이고 논블로킹(Non-blocking)이어야 한다.
    즉, 네트워크 요청이 시작될 때, 게임클라이언트는 응답을 기다리지 않고 지속적으로 가동되어야 한다. 서버가 응답하면 클라이언트에서 이벤트가 트리거되고, 클라이언트 코드의 콜백을 통해 처리된다.
    (iOS : AFNetworking, 브라우저:iQuery.ajax(), C++클라이언트:libcurl, std::async, UNity: UnityWebRequest, Unreal: Htt[Request)
  • JSON을 사용하여 데이터를 전송한다.
    간편하고, 여러 플랫폼에서 사용되며, 구문분석이 빠르고 많은 라이브러리 지원, 데이터유형정보 포함 등 의 이점이 있다.
    페이로드 크기가 큰 경우 gzip으로 압축한다. 대부분의 서버와 클라이언트가 지원하며 용량도 충분한다.
  • HTTP/1.1 및 Keepalives를 사용하고 요청 간에 HTTP연결을 재사용한다.
    이렇게 하면 네트워크 요청 시 게임에서 발생하는 오버헤드가 최소화 된다. 새로운 HTTP소켓을 열면 3방향 TCP핸드셰이크가 필요하며 50ms까지 추가될 수 있다.
  • SSL을 통해 클라이언트에서 서버로 이동하는 모든 중요한 데이터에 항상 POST를 사용한다. 최신 컴퓨터는 SSL을 효율적으로 처리할 수 있으며 오버헤드가 낮다. 또, AWS에서는 Elastic Load Balancer를 통해 SSL 워크로드를 처리하여 서버에서 이 워크로드를 완전히 오프로드 할 수 있다.
  • 보안이 중요한 데이터(예: AWS액세스 키 또는 클라이언트 디바이스의 기타 토큰)를 게임 데이터 ㄸ는 사용자 데이터의 일부로 저장하지 말라.
    액세스키 ID 및 보안 엑세스 키는 이러한 키의 소지자가 AWS CLI(AWS명령줄 인터페이스) Windows PowerShell용 도구, AWS SDK 또는 개별 AWS 서비스에 대한 API를 사용한 직접 HTTP호출을 통해 AWS에 프로그래밍 방식 호출을 전송하는 데 사용된다. 이러한 사용자의 디바이스가 다른사람에게 사용되면 사용자 데이터 및 AWS청구 계정에 액세스 할 수 있는 위험이 발생한다. PC게임의 경우에 키는 메모리에 있을 가능성이 높으며 이것은 쉽게 빼앗길 수 잇다. 따라서 게임 클라이언트에 저장하는 모든 항목이 손상될 것을 가정해야 한다.
  • 예방조치로 게임 클라이언트가 보내는 어떠한 것도 신뢰해서는 안된다.
    모든 항목을 항상 검증해야 하며, 악성 트래픽(SQL주입, XSS등)을 보낼 수 있고, 디바이스의 시간을 과거로 설정하는 것과 같은 사소한 동작을 실행할 수도 있다.


초기 게임 백엔드 시작

  • 게임 사용자가 증가함에 따라 게임을 확장할 수 있도록 상태 비저장 프로토콜을 가능한 많이 사용할 것이다. 많은 게임 기능에 사용할 HTTP/JSON API를 생성하면 인스턴스를 동적으로 추가하고 일시적인 네트워크 문제에서 손쉽게 복구할 수 있다.

  • 게임 백엔드는 HTTP/JSON 과 통신하고, MySQL에 데이터를 저장하며, Amazon Simple Storage Service(Amazon S3)를 바이너리 콘텐츠에 사용하는 서버로 구성된다. 이 유형의 백앤드는 개발이 쉽고 매우 효과적으로 확장된다.

  • 게임 개발자의 일반적 패턴은 웹 서버를 로컬로 실행한 다음, 때가 되면 서버 코드를 클라우드로 푸시하는 것이다. 이렇게 함으로써 AWS Elastic Veanstalk를 사용하여 AWS에 배포하는 프로세스를 크게 간소화 시킬 수 있다.

    사진 첨부 예정

  • Elastic Beanstalk는 Amazon Elastic Compute Cloud(Amazon EC2), Elastic Load Balancing(ELB) 및 Amazon Relational Database Service(Amazon RDS) 같은 다른 AWS서비스를 기반으로 하는 배포관리 서비스이다.

    • Amazon EC2
      클라우드에서 안전하고 크기조정이 가능한 컴퓨팅 파워를 제공하는 웹 서비스
    • ELB
      수신되는 애플리케이션 트래필을 여러 Amazon EC2인스턴스에 자동으로 분산해준다.
      또한, 고가용성, 자동 조정 및 강력한 보안을 갖춘 두 가지 유혀으이 로드 밸런서를 제공한다.
      1. Classic Load Balacer : 애플리케이션 또는 네트워크 수준 정보에 따라 트래픽을 라우팅 (여러 EC2인스턴스에 걸쳐 간단하게 트래픽을 로드 밸런싱하는데 적합)
      2. Application Load Balancer : 고급 라우팅 기능, 마이크로서비스 및 컨테이너 기반 아키텍처가 필요한 애플리케이션에 적합
    • RDS
      관계형 데이터베이스를 손쉽게 설정, 운영 및 확장할 수 있다. Amazon Aurora, PostgreSQL, MySQL등 다수의 익숙한 데이터베이스 엔진 지원.
    • 서버 코드의 zip, war또는 git리포지토리를 Elastic Beanstalk로 배포할 수 있다.

고가용성, 확장성 및 보안

  • 프로덕션 환경의 경우 내결함성을 보장할 수 있는방법으로 게임 백엔드를 배포해야 한다.
  • EC2는 전 세계 여러 AWS 리전에서 호스팅 되며, 많은 수의 고객과 가까운 위치의 리전을 선정해야 한다.
  • 각 리전 안에는 가용 영역이라고 하는 다수의 분리된 위치가 있다. 물리적으로 분리되어 있지만 고속 네트워킹을 통해 연결되있어 함께 사용될 수 있다. 또, 한 리전 내에서 둘 이상의 가용 영역에 서버 로드를 분산하면 게임의 고가용성을 간편하게 개선할 수 있다. 2개의 가용 영역을 사용하면 서버 인스턴스, 데이터베이스 인스턴스 및 캐시 인스턴스를 하나로 페어링 할 수 있으므로 안정성과 비용 사이의 균형을 적절하게 유지할 수 있다.
  • Elastic Beanstalk는 여러 가용 영역에 걸쳐 자동으로 배포한다. 추가 확장성이 필요한 경우 Auto Scaling을 활용하여 이러한 가용 영역의 인스턴스를 추가하고 제거한다.
  • 개발 및 테스트 환경의 경우 단일 가용 영역이면 충분하다. 비용을 저렴하게 유지할 수 있으나 장애 발생시, 혹은 늦은 밤에 개발환경을 사용할 시 프로덕션 환경과 유사한 방식으로 처리하는것이 좋을 수도 있다.
  • 마지막으로 SSL 암호화 및 복호화가 게임 백엔드 서버에서 오프로드 되도록 SSL종료를 처리할 로드 밸런서를 설정한다.

Amazon S3를 사용한 바이너리 게임 데이터

  • 다음으로 각 Elastic Beanstalk 서버 환경에 대한 S3버킷을 생성해야 한다. S3 버킷은 패치, 레벨 및 자산(에셋)같은 바이너리 게임 콘텐츠를 저장한다. Aamzon S3는 HTTP기반 API를 사용하여 데이터를 업로드하고 다운로드 한다. 따라서, 게임 클라이언트에서는 게임 리소스를 다운로드 할때의 게임서버와 동일한 HTTP라이브러리를 사용할 수 있다.
  • 시작하려면 서버와 동일한 리전에서 S3 버킷을 생성한다.
  • 기본적으로 S3버킷은 비공개이며, 콘텐츠 다운로드 시 보안을 위해 사용자인증을 요구한다. 공개로 한다면 쉬울 것이나 권장되지 않는다. 인증을 관리하는 더 좋은 방법은 URL의 일부로 S3 자격 증명을 전달하는 기능인 서명된 URL을 사용하는 것이다. 이 스키마에서는 서명 URL로 리디렉션한다.
  • 마지막으로 게임이 성장하면 CDN(콘텐츠 전송 네트워크)인 Amazon CloudFront를 사용하여 성능을 높이고 데이터 전송 비용을 절감할 수 있다.

AWS Elastic Beanstalk 이상으로 확장

  • 게임 사용자가 증가하면 그에따라 코어 게임 백엔드를 확장하고 수요에 대응해야 한다. 대부분의 호출에 HTTP를 활용하면 변화하는 사용량 패턴에 따라 손쉽게 확장하고 축소할 수 있다. 바이너리 데이터를 AmazonS3에 저장하면 EC2에서 제공할때보다 비용이 절감되며, 데이터 가용성 및 내구성도 자동으로 처리된다. Amazon RDS는 읽기 전용 복제본 같은 Amazon RDS의 기능을 사용하여 지속적으로 늘릴 수 있는 관리형 MySQL 데이터베이스를 제공한다.
  • 게임에 추가 기능이 필요한 경우, 다시 시작할 필요 없이 Elastic Beanstalk에서 다른 AWS서비스로 손쉽게 확장이 가능하다.
  • 물론, 언제든지 다른 AWS서비스를 직접 사용할 수 있다. RDS MySQL DB인스턴스를 온디맨드 자동 조정 SQL DB인 Amazon Aurora Serverless또는 AWS관리형 NoSQL제공인 DynamoDB로 보강할 수 있다.


참조 아키텍처

수평으로 확장 가능한 게임 백엔드에 대한 아키텍처를 살펴본다. 아래 다이어그램은 로그인, 리더보드, 도전, 채팅, 바이너리 게임 데이터, 사용자 생성 콘텐츠, 분석 및 온라인 멀티플레이어 등 다양한 게임 기능을 지원하는 게임 백엔드를 보여준다.

그림 입력 예정

  1. 이중화를 위해 동일한 기능으로 설정된 2개의 가용 영역이 나와 있다. 두 가용 영역은 동일하게 작동하며, 이러한 가용 영역은 처음 Elastic Beanstalk를 사용하여 선택한 2개의 가용영역과 동일할 수 있다.

  2. Elastic Beanstalk를 사용하여 시작한 것과 동일할 수 있는 HTTP/JSON서버 및 마스터/슬레이브 DB이다. 가능한 많은 게임 기능을 HTTP/JSON계층에서 계속해서 빌드한다. HTTP Auto Scaling을 활용하여 사용자 수요에 따라 EC2 HTTP 인스턴스를 자동으로 추가하고 제거할 수 있다.

  3. 처음 바이너리 데이터에 대해 생성한 것과 동일한 S3버킷을 사용할 수 있다. AmazonS3는 탁월한 확장성을 제공하도록 설계되었으며 지속적인 튜닝이 거의 필요하지 않다. 게임 리소스와 사용자 트래픽이 계속해서 확장하면 S3앞에 Amazon CloudFront를 추가하여 다운로드 성능을 높이고 비용을 절감할 수 있다.

  4. 게임에 상태 저장 소켓이 필요한 기능(예: 채팅 또는 멀티플레이어 게임플레이)이 있는경우, 이러한 기능은 일반적으로 기능을 위한 코드만 실행하는 게임서버를 통해 처리된다. HTTP인스턴스와 분리된 EC2인스턴스에서 실행되게 된다.

  5. 게임이 커지고, 데이터베이스 로드가 증가하면 캐싱을 추가해야 한다. 일반적으로 이작업에서 AWS 관리형 캐싱 서비스인 Amazon ElasticCache가 사용된다. 자주 액세스되는 항목을 ElasticCache에 캐싱하면 데이터베이스의 읽기 쿼리가 오프로드된다.

  6. 서버 작업 중 일부를 비동기식 작업으로 이동하고 Amazon Simple Queue Service (SQS)를 사용하여 이 작업을 조정하는 것이다. 이렇게 하면 둘 이상의 구성 요소가 있고 각 구성 요소에 다른 참여 구성 요소에 대한 지식이 거의 없지만 상호 운용되는, 느슨하게 결합된 아키텍처를 만들 수 있다. 예로, 게임에서 사용자가 사진 또는 사용자 지정 캐릭터같은 자산을 업로드하고 공유할 수 있는 경우, 이미지 크기 조정 같은 시간 집약적인 작업을 백그라운드 작업으로 실행해야 한다. 이렇게하면 게임 응답시간이 빨라짐과 동시에 HTTP서버 인스턴스의 로드가 감소한다.

  7. 데이터베이스 로드가 계속해서 증가하면 Amazon RDS 읽기 전용 복제본을 추가하여 데이터베이스 읽기를 추가로확장할 수 있다. 복제본에서 읽고 마스터베이스에는 쓸 때만 액세스하므로 기본 데이터베이스의 로드가 감소하게될 것이다.

  8. 리더보드 같은 기능을 위해 기본 데이터베이스를 보완하거나, Atomic Counter같은 NoSQL기능을 활용하기 위해 Amazon DynamoDB와 같은 NoSQL서비스의 도입을 결정하게 될 수 있다.

  9. 게임에 푸시 알림이 포함되는 경우 Amazon Simple Notification Service(Amazon SNS)와 모바일 푸시에 대한 지원을 사용하여 여러 모바일 플랫폼에 푸시 메세지를 보내는 프로세스를 간소화 할 수 있다. EC2 인스턴스에서 AmazonSNS메시지를 수신하여 현재 게임서버에 연결된 모든플레이어에게 메세지를 브로드캐스트하는 등의 작업을 수행할 수 있다.

REST API 로서의 게임

수평적 확장성을 사용하려면 대부분의 게임 기능을 HTTP/JSON API를 사용하여 구현해야 한다. 이 API는 일반적으로 REST아키텍처 패턴을 따른다.

profile
Talking Potato

0개의 댓글