클라우드와 서버 관리
전용·리슨 서버의 차이를 이해하고 클라우드 배포·확장·보안·비용을 고려한 운영 구조를 선택합니다.
멀티플레이어 게임을 출시하는 날에는 평소의 몇 배가 넘는 플레이어가 한꺼번에 몰리고, 몇 주 뒤에는 그 수가 크게 줄어듭니다. 가장 많을 때에 맞춰 서버를 사 두면 한산할 때는 비용이 낭비되고, 적게 사 두면 출시일에 접속조차 못 하는 플레이어가 생깁니다. 서버가 불안정하면 플레이어의 경험이 바로 무너지므로, 서버를 어떻게 구성하고 늘리고 줄일지는 게임 운영의 중심 과제입니다.
핫픽스와 업데이트 전략에서 업데이트를 전달하는 방법을 보았으니, 이 글에서는 그 바탕이 되는 서버 인프라를 다룹니다. 게임 서버가 맡는 일과 클라우드의 이점을 살펴보고, 전용 서버, 리슨 서버, 서버리스 같은 구축 방식과 클라우드 서비스의 선택 기준, 언리얼 전용 서버를 빌드해 배포하는 과정, 그리고 서버를 안전하게 늘리고 줄이는 운영 방법을 정리합니다.
게임 서버가 맡는 일
멀티플레이어 게임 서버는 데이터를 주고받는 데서 그치지 않습니다. 모든 플레이어에게 게임 월드의 확정된 기준 상태를 제공하고 맞추며, 이를 서버 권한(server authority)이라고 합니다. 피해 계산, 충돌 처리, 아이템 획득 같은 중요한 게임 로직을 한곳에서 처리해 치트를 막고, 플레이어의 접속과 해제를 관리해 안정적인 통신 환경을 제공합니다. 플레이어 데이터와 게임 진행을 저장하고 관리하며, 플레이어들을 매칭하고 게임 세션을 만들고 관리하는 일도 합니다. 그래서 서버가 불안정하면 곧바로 플레이어의 불만으로 이어지고 게임의 성공에 큰 영향을 줍니다.
클라우드를 쓰는 이유
모든 인프라를 직접 운영하면 비용과 인력 부담이 크기 때문에, 실무에서는 AWS, Google Cloud, Microsoft Azure 같은 클라우드 서비스를 활용해 확장성과 운영 효율을 얻는 경우가 많습니다.
클라우드의 첫 번째 이점은 확장성(scalability)입니다. 플레이어 수에 따라 서버 자원을 자동으로 늘리거나(scale out) 줄일(scale in) 수 있어, 동시 접속자가 몰리는 출시 초기나 대규모 이벤트에 특히 쓸모가 있습니다. 두 번째는 고가용성(high availability)으로, 서버를 여러 장애 영역에 나눠 둘 수 있습니다. 다만 진행 중인 게임 세션을 복구하고, 다시 접속하게 하고, 상태를 보존하는 일은 따로 설계해야 하며, 여러 리전에 배치한다고 중단 없는 서비스가 보장되지는 않습니다.
비용 면에서는 필요한 만큼만 쓰고 그만큼 내는 종량제(pay-as-you-go) 덕분에 초기 투자를 줄이고 놀리는 자원도 줄일 수 있습니다. 하드웨어와 관리형 서비스의 일부 운영은 공급자가 맡지만, 직접 운영하는 가상 머신의 운영 체제, 게임 코드, 접근 권한은 선택한 서비스에서 공급자와 나눠 맡는 범위에 맞춰 직접 관리해야 합니다. 또 공급자들은 전 세계 주요 지역에 데이터 센터를 두고 있어, 플레이어와 가까운 곳에 서버를 두어 지연 시간을 줄일 수 있습니다.
서버를 구축하는 방식
전용 서버
전용 서버(dedicated server)는 게임 클라이언트와 따로 서버 로직만 실행하는 독립적인 빌드로, 언리얼은 TargetType.Server 타깃으로 이를 지원합니다. 클라우드의 가상 머신 인스턴스에 이 빌드를 배포해 실행하고, 매치메이커(matchmaker) 서비스가 플레이어를 서버 인스턴스에 연결합니다.
서버가 확실한 권한을 가지므로 치트를 막는 데 가장 효과적이고, 클라이언트의 렌더링 부담이 없어 게임 로직 처리 성능이 좋으며, 클라이언트가 크래시해도 서버에는 영향이 없습니다. 대신 게임 서버 프로세스와 여유 수용량을 운영하는 비용이 듭니다. 가상 머신 하나에 프로세스 여러 개를 둘 수도 있으므로, 세션 수와 가상 머신 수를 하나씩 대응시켜 생각하지 않습니다. FPS, AOS, MMORPG처럼 경쟁 요소가 강하고 치트에 민감한 게임에 알맞습니다.
리슨 서버
리슨 서버는 플레이어 한 명의 게임 클라이언트가 서버 역할도 함께 하는 방식입니다. 특정 플레이어가 호스트가 되어 자신의 PC에서 서버를 실행하고, 다른 플레이어들이 그 호스트에 접속합니다. 게임 세션을 위한 전용 서버 비용을 줄일 수 있지만, 인증, 매치메이킹, 릴레이 같은 보조 서비스 비용은 따로 듭니다.
단점도 분명합니다. 호스트가 게임을 끄면 세션도 끝나고, 호스트의 업로드 속도나 NAT 문제 같은 네트워크 환경이 모든 플레이어의 지연 시간을 정합니다. NAT는 공유기 뒤의 여러 장치가 공인 주소 하나를 나눠 쓰게 하는 주소 변환이라서, 바깥에서 호스트로 들어오는 연결을 막을 수 있습니다. 동작과 포트 포워딩은 네트워크 교재의 NAT와 DHCP에서 다룹니다. 호스트 클라이언트가 서버 권한을 가지므로 치트에도 아주 취약합니다. 그래서 협동 중심의 소규모 멀티플레이어 게임, 친구들과 즐기는 캐주얼 게임, 운영 비용이 중요한 독립 개발사에 알맞습니다.
서버리스
서버리스(serverless)는 서버를 준비하거나 관리하지 않고 백엔드 코드를 실행하는 클라우드 서비스로, AWS Lambda나 Google Cloud Run functions가 그 예입니다. 리더보드 갱신, 아이템 구매 검증, 사용자 인증처럼 짧고 가끔 실행되는 백엔드 로직에 씁니다. 요청량에 맞춰 실행하고 확장할 수 있지만, 요청, 실행, 네트워크, 최소 인스턴스 같은 실제 요금 항목을 모두 더해 봐야 하며 늘 더 싼 것은 아닙니다. 처음 실행할 때의 지연(콜드 스타트) 때문에 실시간 게임 로직에는 맞지 않고, 게임 안의 비동기 백엔드 기능이나 웹 서비스 연동에 알맞습니다.
클라우드 서비스 고르기
주요 클라우드 공급자는 게임 개발을 위한 여러 서비스를 제공합니다. AWS에는 가상 서버인 EC2, 전용 게임 서버 호스팅과 매치메이킹, 확장을 맡는 관리형 서비스인 Amazon GameLift Servers, 서버리스인 Lambda, 스토리지인 S3, NoSQL 데이터베이스인 DynamoDB가 있으며, GameLift Servers는 언리얼과의 통합을 지원합니다. Google Cloud에는 가상 머신인 Compute Engine, 함수 실행 서비스인 Cloud Run functions, 데이터베이스인 Spanner와 Firestore가 있습니다. Microsoft Azure에는 Azure Virtual Machines, 서버리스인 Azure Functions, 그리고 매치메이킹, 리더보드, 인증 같은 백엔드 서비스를 제공하는 PlayFab이 있습니다.
고를 때는 여러 가지를 따집니다. 각 서비스의 요금 모델과 예상 사용량으로 총 운영 비용을 추산하고, 플레이어가 있는 지역과 가까운 데이터 센터가 있는지 봅니다. 예상 동시 접속자의 변동에 맞춰 확장할 수 있는지, 언리얼과의 통합이 쉽고 관리 도구가 효율적인지, 데이터 암호화와 접근 제어 같은 보안 기능이 있는지, 문제가 생겼을 때의 기술 지원과 개발 커뮤니티가 활발한지도 함께 확인합니다.
언리얼 전용 서버를 빌드하고 배포하기
Epic의 공식 전용 서버 안내는 멀티플레이 C++ 프로젝트와 소스에서 빌드한 엔진을 전제로 합니다. 엔진과 프로젝트의 버전을 고정하고, 기존 Game, Editor 타깃과 같은 빌드 설정을 씁니다.
먼저 프로젝트의 Source 폴더에 [ProjectName]Server.Target.cs 파일을 만들어 전용 서버 타깃을 정의합니다.
using UnrealBuildTool;
using System.Collections.Generic;
public class MyGameServerTarget : TargetRules
{
public MyGameServerTarget(TargetInfo Target) : base(Target)
{
Type = TargetType.Server;
DefaultBuildSettings = BuildSettingsVersion.V7;
IncludeOrderVersion = EngineIncludeOrderVersion.Unreal5_8; // Your engine version
ExtraModuleNames.Add("MyGame"); // Your game module name
}
}Type = TargetType.Server가 이 타깃을 전용 서버로 만들고, ExtraModuleNames에 게임 모듈 이름을 넣습니다. 예제의 MyGame은 실제 게임 모듈 이름으로 바꿉니다. DefaultBuildSettings의 V7과 IncludeOrderVersion의 Unreal5_8은 빌드 기본값과 include 순서를 정하는 값으로, 5.8의 Blank 템플릿이 만드는 타깃 파일과 같은 값입니다. 5.8의 UBT는 Unreal5_5 이하의 include 순서를 지원하지 않는 값으로 표시하므로, 쓰는 엔진이 지원하는 값과 프로젝트의 기존 타깃에 맞춰 고릅니다. 기존 Game 타깃이 쓰는 값과 같게 맞추거나, 늘 엔진의 최신 기본값을 따르려면 BuildSettingsVersion.Latest와 EngineIncludeOrderVersion.Latest를 쓸 수 있습니다.
다음으로 프로젝트 파일을 갱신하고 Development Server 같은 서버 타깃을 빌드합니다. 에디터의 플랫폼 메뉴에서 해당 플랫폼의 빌드 타깃(Build Target)을 서버로 정해 서버용 콘텐츠를 쿠킹하고, 배포에 필요한 스테이지와 패키지 단계를 진행합니다.
그다음 AWS EC2나 Google Compute Engine 같은 클라우드 가상 머신을 만들고, 알맞은 운영 체제(Windows Server나 Linux)와 사양(CPU 코어, 메모리)을 고릅니다. 패키징한 전용 서버 빌드를 SFTP 같은 방법으로 그 인스턴스에 올리고, 인스턴스의 방화벽(AWS의 보안 그룹 같은 것)에서 실제로 쓰는 게임 포트와 프로토콜만 허용합니다. 기본 게임 포트의 예는 UDP 7777이며, 추가로 필요한 포트는 선택한 네트워크 드라이버와 서비스 설정에서 확인합니다.
이제 인스턴스에서 MyGameServer.exe -log -port=7777처럼 전용 서버 실행 파일을 실행합니다. 실행한 뒤에는 서버 로그를 실시간으로 지켜보고, AWS CloudWatch 같은 클라우드의 모니터링 도구로 CPU 사용률, 메모리, 네트워크 트래픽을 추적합니다.
마지막으로 확장과 자동화를 설정합니다. 대기열, 빈 세션 슬롯, 프로세스가 준비되는 데 걸리는 시간을 기준으로 확장 정책을 정하고, 줄일 서버에는 새 배정을 막은 뒤 진행 중인 세션을 마치거나 넘기는 드레인(drain) 정책을 적용합니다. CPU 사용률만 보고 서버를 끄면 진행 중인 세션이 끊길 수 있습니다. 프로세스가 살아 있다는 것과 실제로 세션을 받을 수 있는 상태라는 것은 다르므로, 빌드, 지역, 포트, 가용 슬롯을 매치메이커가 읽는 정보와 맞춥니다.
서버를 안전하게 늘리고 줄이기
새 배정 준비와 안전한 축소를 따로 확인합니다
시작 준비→새 배정 가능→드레인 시 새 배정 중단→세션/상태 보존 완료 검사→종료의 운영 상태 전이다. CPU/시간 초과만으로 종료하지 않는다.
UNREAL C++ · CH10-4
새 배정 준비와 안전한 축소를 따로 확인합니다
전용 서버 프로세스의 운영 정책 예시입니다. 프로세스가 실행 중이라는 사실만으로 세션을 받을 수 있는 것은 아니며, 축소 전에는 새 배정을 중단해야 합니다.
화살표는 운영 정책의 전환 조건입니다. 준비 전에는 새 배정을 막고, 종료 조건이 남으면 드레인을 유지합니다. 준비 완료가 모든 순간 빈 슬롯을 보장하거나 드레인 시간 초과가 안전한 종료를 증명하지 않습니다.
시작 중 · 새 배정 대기
빌드·지역·게임 포트·필수 초기화와 빈 세션 슬롯을 확인합니다. 프로세스 생존 검사와 세션 수용 준비 검사를 구분합니다.
준비 완료 · 가용 슬롯에만 배정
매치메이커가 실제 수용 정보와 일치하는 프로세스에 새 세션을 배정합니다. 새 인스턴스가 준비되기까지 걸리는 시간과 대기열을 확장 판단에 포함합니다.
드레인 중 · 새 배정 중단
축소할 프로세스를 새 배정 대상에서 빼고 기존 세션의 종료 또는 설계된 인계를 기다립니다. 낮은 CPU 사용률만 보고 활성 세션을 끊지 않습니다.
종료 조건 확인 · 자원 회수
기존 세션의 종료·인계와 필요한 상태 보존이 끝났는지 확인한 뒤 프로세스·자원을 정리합니다. 실패 시의 재접속·복구 절차도 별도로 검증합니다.
프로세스 ≠ VM ≠ 세션
한 VM에 여러 프로세스를 둘 수 있습니다. 실제 배치·수용 모델에 맞춰 용량을 정하며 세션 수와 VM 수를 일대일로 가정하지 않습니다.
이 그림의 적용 범위
시작→준비→드레인→종료는 정책을 설명하는 예시입니다. 관리형 서비스의 API 상태 이름이나 구현·배포 완료를 나타내지 않습니다.
이 예의 조건
- 본문과 원 도표에 제시된 사례의 입력·조건을 사용합니다. 설명용 수치나 독립 비교 경로는 각 단계에 표시합니다.
- 현재 상태·값과 전환 근거의 위치는 모든 단계에서 같습니다. 조건이 맞지 않거나 실행되지 않은 경로를 성공한 동작으로 해석하지 않습니다.
관계도의 보충 설명
| 범위 | 원문 |
|---|---|
| 관계·조건 설명 | 시작 중에 필수 초기화와 맵·포트·빈 슬롯을 확인하면 준비 완료가 된다. 축소 대상 선택 시 새 배정을 중단해 드레인한다. 기존 세션 종료 또는 설계한 인계와 상태 보존이 모두 끝났으면 종료하고, 미충족이면 드레인 상태로 돌아가 확인한다. CPU 저하나 시간 초과만으로 종료되지 않으며 클라우드 API 구현의 상태 이름이 아니다. |
| 관찰·상황 | 값·보충 정보 | 변화·이유 |
|---|---|---|
| 준비 검사·완료 필수 초기화·맵·포트와 빈 슬롯 조건을 확인하면 준비 완료 상태에서 가용 슬롯에만 배정한다. |
|
|
| 축소 선택·드레인 축소 대상으로 선택되면 새 배정을 중단하고 기존 세션의 종료·인계를 기다린다. |
|
|
| 종료 조건 세션 처리와 상태 보존이 끝났는지 확인해 종료한다. |
|
|
새 배정 준비와 안전한 축소를 따로 확인합니다
시작 준비→새 배정 가능→드레인 시 새 배정 중단→세션/상태 보존 완료 검사→종료의 운영 상태 전이다. CPU/시간 초과만으로 종료하지 않는다.
UNREAL C++ · CH10-4
새 배정 준비와 안전한 축소를 따로 확인합니다
전용 서버 프로세스의 운영 정책 예시입니다. 프로세스가 실행 중이라는 사실만으로 세션을 받을 수 있는 것은 아니며, 축소 전에는 새 배정을 중단해야 합니다.
화살표는 운영 정책의 전환 조건입니다. 준비 전에는 새 배정을 막고, 종료 조건이 남으면 드레인을 유지합니다. 준비 완료가 모든 순간 빈 슬롯을 보장하거나 드레인 시간 초과가 안전한 종료를 증명하지 않습니다.
시작 중 · 새 배정 대기
빌드·지역·게임 포트·필수 초기화와 빈 세션 슬롯을 확인합니다. 프로세스 생존 검사와 세션 수용 준비 검사를 구분합니다.
준비 완료 · 가용 슬롯에만 배정
매치메이커가 실제 수용 정보와 일치하는 프로세스에 새 세션을 배정합니다. 새 인스턴스가 준비되기까지 걸리는 시간과 대기열을 확장 판단에 포함합니다.
드레인 중 · 새 배정 중단
축소할 프로세스를 새 배정 대상에서 빼고 기존 세션의 종료 또는 설계된 인계를 기다립니다. 낮은 CPU 사용률만 보고 활성 세션을 끊지 않습니다.
종료 조건 확인 · 자원 회수
기존 세션의 종료·인계와 필요한 상태 보존이 끝났는지 확인한 뒤 프로세스·자원을 정리합니다. 실패 시의 재접속·복구 절차도 별도로 검증합니다.
프로세스 ≠ VM ≠ 세션
한 VM에 여러 프로세스를 둘 수 있습니다. 실제 배치·수용 모델에 맞춰 용량을 정하며 세션 수와 VM 수를 일대일로 가정하지 않습니다.
이 그림의 적용 범위
시작→준비→드레인→종료는 정책을 설명하는 예시입니다. 관리형 서비스의 API 상태 이름이나 구현·배포 완료를 나타내지 않습니다.
이 예의 조건
- 본문과 원 도표에 제시된 사례의 입력·조건을 사용합니다. 설명용 수치나 독립 비교 경로는 각 단계에 표시합니다.
- 현재 상태·값과 전환 근거의 위치는 모든 단계에서 같습니다. 조건이 맞지 않거나 실행되지 않은 경로를 성공한 동작으로 해석하지 않습니다.
관계도의 보충 설명
| 범위 | 원문 |
|---|---|
| 관계·조건 설명 | 시작 중에 필수 초기화와 맵·포트·빈 슬롯을 확인하면 준비 완료가 된다. 축소 대상 선택 시 새 배정을 중단해 드레인한다. 기존 세션 종료 또는 설계한 인계와 상태 보존이 모두 끝났으면 종료하고, 미충족이면 드레인 상태로 돌아가 확인한다. CPU 저하나 시간 초과만으로 종료되지 않으며 클라우드 API 구현의 상태 이름이 아니다. |
| 관찰·상황 | 값·보충 정보 | 변화·이유 |
|---|---|---|
| 준비 검사·완료 필수 초기화·맵·포트와 빈 슬롯 조건을 확인하면 준비 완료 상태에서 가용 슬롯에만 배정한다. |
|
|
| 축소 선택·드레인 축소 대상으로 선택되면 새 배정을 중단하고 기존 세션의 종료·인계를 기다린다. |
|
|
| 종료 조건 세션 처리와 상태 보존이 끝났는지 확인해 종료한다. |
|
|
위 그림은 전용 서버 프로세스를 운영하는 정책의 예로, 새 배정을 받을 준비와 안전한 축소를 따로 확인하는 흐름을 보여 줍니다. 시작 중인 프로세스는 새 배정을 받지 않다가, 필수 초기화와 맵, 포트, 빈 슬롯을 확인하면 준비 완료가 되어 가용 슬롯에만 세션을 받습니다. 축소 대상으로 선택되면 드레인 상태로 바뀌어 새 배정을 멈추고 기존 세션을 유지합니다. 그다음 기존 세션의 처리와 상태 보존이 모두 끝났는지 확인해, 둘 다 충족되면 종료하고 자원을 회수하며, 그렇지 않으면 드레인 상태에서 기다립니다. 그림의 설명처럼 CPU 사용률이 낮거나 시간이 지났다는 것만으로는 종료하지 않으며, 이 상태 이름은 클라우드 API에 구현된 이름이 아닙니다.
그림의 아래쪽은 각 상태에서 할 일을 정리합니다. 시작 중에는 빌드, 지역, 게임 포트, 필수 초기화, 빈 세션 슬롯을 확인하며, 프로세스가 살아 있는지 보는 검사와 세션을 받을 준비가 되었는지 보는 검사를 구분합니다. 준비 완료 상태에서는 매치메이커가 실제 수용 정보와 맞는 프로세스에만 새 세션을 배정하고, 새 인스턴스가 준비되기까지 걸리는 시간과 대기열을 확장 판단에 넣습니다. 드레인 중에는 줄일 프로세스를 새 배정 대상에서 빼고, 기존 세션이 끝나거나 설계한 대로 넘어가기를 기다리며, 낮은 CPU 사용률만 보고 진행 중인 세션을 끊지 않습니다. 종료 조건을 확인하는 단계에서는 세션의 종료나 인계, 필요한 상태 보존이 끝났는지 확인한 뒤 프로세스와 자원을 정리하고, 실패했을 때의 재접속과 복구 절차도 따로 검증합니다.
그림은 프로세스, 가상 머신, 세션이 서로 다르다는 점도 짚습니다. 가상 머신 하나에 프로세스 여러 개를 둘 수 있으므로, 실제 배치와 수용 모델에 맞춰 용량을 정하고 세션 수와 가상 머신 수를 하나씩 대응시키지 않습니다. 시작, 준비, 드레인, 종료의 흐름은 정책을 설명하기 위한 예일 뿐, 관리형 서비스의 상태 이름이나 구현, 배포가 끝났다는 뜻이 아닙니다. 단계 그림도 준비를 검사해 가용 슬롯에만 배정하고, 축소 대상이 되면 새 배정을 멈추고, 세션 처리와 상태 보존을 확인한 뒤에야 종료하는 순서를 따라갑니다.
용량을 계산해 보기
계산 연습을 위해 세션 하나에 최대 10명, 프로세스 하나에 세션 하나, 가상 머신 하나에 프로세스 세 개를 둔다고 정합시다. 플레이어 210명을 모두 받으려면 세션이 210/10 = 21개, 프로세스도 21개, 가상 머신은 21/3 = 7대가 필요합니다. 새 배정에 쓸 빈 프로세스 세 개를 더 준비하려면 프로세스는 모두 24개가 되어 가상 머신은 24/3 = 8대가 필요합니다. 실제로 세션 하나에 몇 명을 받을지, 프로세스를 어떻게 배치할지, 여유를 얼마나 둘지는 대상 환경의 부하 시험으로 정해야 하며, 이 값은 어떤 제품이 보장하는 용량이 아닙니다.
새로 띄운 프로세스는 서버용 맵, 필수 초기화, 게임 포트, 준비 정보가 모두 맞아야 세션을 배정합니다. Epic의 Setting Up Dedicated Servers 문서는 소스 엔진과 멀티플레이 C++ 프로젝트에서 서버 타깃을 빌드하고, 쿠킹하고, 접속을 시험하는 과정을 다루므로, 서버의 기본 맵(Server Default Map)과 서버용 콘텐츠도 함께 확인합니다. 이 글의 가상 머신 배치와 드레인 규칙은 그와 별개인 운영 정책의 예입니다.
서버의 보안과 최적화
클라이언트의 입력은 어느 것도 그대로 믿지 말고 서버에서 다시 검증해 치트를 막습니다. 서비스 거부(DoS, DDoS) 공격에는 클라우드의 기본 방어 기능을 쓰거나 별도의 방어 솔루션을 도입합니다. 민감한 데이터는 전송할 때와 저장할 때 모두 암호화하고, 서버 관리와 API 접근에는 엄격한 권한 관리를 적용하며, 서버 인스턴스와 백엔드 서비스에는 꼭 필요한 최소한의 권한만 줍니다.
전용 서버 빌드에도 CPU, GPU 병목 현상 해결에서 다룬 Tick, 물리, AI 최적화 같은 CPU 최적화를 적용해, 적은 자원으로 더 많은 플레이어를 받을 수 있게 합니다. 장애가 생기면 같은 시간대의 서버 로그, 틱 시간, 메모리, 세션 수용량을 함께 대조하고, 새 인스턴스의 준비, 기존 세션의 드레인, 배포가 실패했을 때의 복구 절차를 실제 운영 환경에서 확인합니다.
정리
- 게임 서버는 상태 동기화, 핵심 로직 처리, 연결 관리, 데이터 저장, 매치메이킹을 맡으며, 서버의 안정성이 플레이어 경험을 좌우합니다.
- 클라우드는 확장성, 고가용성, 종량제, 글로벌 네트워크를 제공하지만, 세션 복구와 직접 운영하는 부분의 관리는 따로 설계해야 합니다.
- 전용 서버는 치트 방지와 성능에 유리하지만 운영 비용이 들고, 리슨 서버는 비용이 적지만 호스트에 의존하며, 서버리스는 비동기 백엔드에 알맞습니다.
- 전용 서버는
TargetType.Server타깃을 만들어 빌드하고, 서버용 콘텐츠를 쿠킹해 배포하며, 쓰는 포트만 열고 모니터링합니다. - 프로세스 생존과 세션 수용 준비는 다르며, 축소할 서버는 새 배정을 멈추고 세션 처리와 상태 보존이 끝난 뒤에 종료합니다.
- 프로세스, 가상 머신, 세션의 수는 서로 다르므로 실제 배치와 부하 시험으로 용량을 정합니다.
연습 문제
1. 230명을 받으려면
같은 수용 모델(세션당 10명, 프로세스당 세션 하나, 가상 머신당 프로세스 세 개)에서 플레이어 230명을 받고 빈 프로세스 세 개를 더 준비하려면, 세션, 필요한 프로세스, 가상 머신은 각각 몇 개일까요?
해설 보기
세션은 230/10 = 23개이고, 빈 프로세스 세 개를 더하면 필요한 프로세스는 26개입니다. 가상 머신 하나에 세 개씩 두므로 26/3을 올림해 9대가 필요합니다. 9대에는 최대 27개의 프로세스 자리가 있으므로, 요구한 빈 프로세스 세 개 외에 자리가 하나 더 남습니다. 요구한 여유와 올림 때문에 생긴 추가 자리를 구별해 둡니다.
2. CPU가 낮으니 꺼도 될까
줄이려는 가상 머신에서 아직 두 프로세스가 세션을 진행 중인데 CPU 사용률은 낮습니다. 바로 그 가상 머신을 종료해도 될까요? 드레인 제한 시간이 지났다는 사실만으로 상태 보존이 끝났다고 판단해도 될까요?
해설 보기
바로 종료하면 안 됩니다. CPU 사용률이 낮아도 세션이 진행 중이라면 플레이어가 있으므로, 먼저 드레인 상태로 바꿔 새 배정을 막고, 진행 중인 세션이 끝나거나 설계한 대로 넘어가며 상태가 보존되었는지를 확인해야 합니다.
제한 시간이 지났다는 것도 상태 보존이 끝났다는 확인이 아닙니다. 시간이 지난 뒤 강제로 종료할지, 플레이어를 다시 접속시킬지, 어떻게 복구할지는 따로 기준을 정하고 시험해 둡니다. 이 문제는 실제 서버를 실행하거나 클라우드에 배포해 확인한 기록이 아닙니다.
3. 리슨 서버로 경쟁 게임을
랭킹이 걸린 1대1 경쟁 게임을 비용 때문에 리슨 서버로 운영하려 합니다. 어떤 문제가 생길 수 있을까요?
해설 보기
리슨 서버에서는 호스트의 클라이언트가 서버 권한을 가지므로, 호스트가 자기 쪽 게임을 조작하면 결과를 유리하게 바꿀 수 있어 치트에 아주 취약합니다. 랭킹처럼 결과의 공정성이 중요한 게임에서는 큰 문제입니다. 또 호스트의 네트워크가 상대의 지연 시간을 정하므로 호스트가 유리해지고, 호스트가 나가면 경기도 끝납니다. 경쟁 요소가 강한 게임에는 서버가 확실한 권한을 갖는 전용 서버가 더 알맞습니다.
이것으로 10장을 마칩니다. 10장에서는 빌드, 쿡, 스테이지, 패키지로 나뉜 패키징과 플랫폼별 요구 사항, 콘솔 명령과 디버거, 로그와 크래시 보고로 문제를 찾는 방법, 핫픽스와 업데이트를 전달하는 패치 방식, 그리고 전용 서버를 빌드해 클라우드에서 안전하게 늘리고 줄이는 운영 방법을 살펴봤습니다. 다음 장의 플러그인 개발부터는 플러그인과 에디터 확장, AI와 행동 트리, 머신러닝과 실시간 렌더링 같은 고급 주제를 다룹니다.