출처 :
1. AWSKRUG 아키텍처 모임의 '윤평호' 님 발표
2. https://www.slideshare.net/ssuser052dd11/igc-2017
3. https://15466.courses.cs.cmu.edu/lesson/network
일반적인 싱글/멀티 플레이어 게임에서는 다음과 같이 처리한다.
1. Inputs > Simulate > Render > Wait > Inputs >... 반복
2. Simulate는 State 값을 받아 Inputs에 반영
3. Inputs는 events timer로도 작동
일반적인 온라인 멀티 플레이어 게임에서는 다음과 같이 처리한다.
1. Inputs이 들어오면 Server로 events를 보내 Simulate한다.
2. 다음은 Render 단계를 거치는데, Server에서 state info를 받아 Render 과정에 반영한다.
States 정보는 Simulate에도 전달된다.
3. Render 단계가 끝나면 Wait 단계로 돌입하고, 다시 Inputs 단계로 돌아간다. 반복.
(UDP는 당연)
어떤 구성이든 간데 온라인 게임에서 주의해야 할 점은... 네트워크 송수신은 언제 받는다는 보장이 없다는 것.
게임 아키텍처 유형
- 비동기형
대표적으로 체스, 바둑 등이 있다. 요즘 게임으로 치면 클래시 오브 클랜이나 탕탕특공대.
-> 대충 모바일/소셜 게임
비동기형 게임은 게임 한 판이 끝나야 데이터를 서버(or DB)에 저장한다(동기화).
게임 진행은 클라이언트에서 하고, 끝나면 저장하는 방식이니 튕기면 롤백된다.
구성이야 고만고만하다.
-> 웹 서비스(2-Tier/3-Tier) + WebSocket
-> GameLift(EC2), EKS/ECS, Serverless
(어떤 방식을 선택하던 DB 종류 선정은 신중하게)
(ex : Serverless는 Lifecycle 문제로 1회성 접속을 제공하는 DB가 적절하다 : DynamoDB)
-> State 관리는 클라이언트/서버
-> 동기화 관리는 Cache나 DB로 한다.
- 지속형
MMOG(Massive Multiplayer Online Games) 유형의 게임. 요즘 게임으로 치면 로스트아크/WOW 같은 게임.
Client-Server(CS) 구조 :
CS 간에서 발생하는 다양한 오차는 Dead Reckoning이나 Lag Compensation 등으로 보정한다.
구성이야 고만고만하다 2
-> GameLift(EC2), EKS/ECS
State 관리도, 동기화도 서버에서 한다.
- 세션형
MOBA(Multiplayer Online Battle Arena), FPS(First-Person Shooter), RTS(Real-Time Strategy), Sports 류의 게임.
요즘 게임으로는 배틀그라운드, 피파 온라인, TACTICOOL, LOL 등이 있다.
연결 구조에 따라 구성이 달라진다 : P2P, Hosting, Dedicated
-> P2P : Player 여럿이 있으면 각각 1:1로 연결된다. 연결이 Mesh 구조가 된다.
-> Hosting : Player 하나가 Host가 되어 나머지 Player들이 Host에 연결된다.
-> Dedicated : 모든 Player들이 Dedicated Server로 접속한다.
구성이야 고만고만하다 3
-> GameLift(EC2), EKS/ECS
동기화 방식이 좀 갈린다.
-> FPS/RTS/MOBA/Sports : 서버 동기화
-> RTS/AOS : Lock-Step 등
※ Lock-Step?
-> 모든 Player(Peer)의 입력이 모이면 해당 Round를 처리(Simulate)하고 Rendering
-> 특정 Peer의 정보가 제시간에 도착하지 않으면 Block
-> 다 모아서 한 번에 처리하니 특정 클라이언트가 튀는 현상은 없지만, 하나가 느려지면 전체적으로 느려진다.
게임 시스템에 기본적으로 기대되는 요소들은....
1. 입력이 빠르게 전달될 것
-> 입력해야 하는 정보 최소화, 재전송 X, 재확인 X 등
2. 빠르게 처리할 것
-> 트랜잭션 최소화, 빠른 I/O, 비동기 DB 처리, 유휴 리소스 최소화 등
3. 변경 상태를 빠르게 전달할 것
-> 전달해야 하는 정보 최소화, 라우팅 최적화 등
4. 변경 상태가 빠르게 반영(표현)될 것
-> 내부 프로세스(파이프라인) 최적화, Lock 최소화
5. 모든 플레이어에게 공정할 것
-> 지연 시간 차이로 인해 게임 플레이에 지장이 생기면 안 됨
-> 지역이 비슷해도 ping time은 제각각이다
-> TACTICOOL의 경우, 평균 ping time이 비슷한 조건의 플레이어를 매칭 시킨다.
-> 데이터 전송량을 줄이고 처리 속도를 올리기 위해 JSON 대신 Binary 사용
-> 아무튼 여기저기서 다이어트해서 정보 최소화
Q&A
1. 실시간성이 필요한 종류의 게임(LoL/Starcraft 등)은 실시간 소켓을 어떻게 만드는지?
-> 전송 속도 문제로 UDP 사용. 짧은 시간 동안 들어온 모든 입력 이벤트를 묶어서 전송한다(크면 나눠서 전송).
2. 퀘스트 완료 시 서버로 데이터를 보내는데, 이에 대한 악의적인 조작(manipulating)의 검증은 어떻게 하는지?
-> 기본적으로는 클라이언트와 서버 간의 고유한 키를 이용해 암호화하고, 서버에서 내용을 검증.
-> 클라이언트는 언제든 해킹될 수 있기에 암호화된 내용도 변조될 수 있다.
-> 플레이어 경험에 영향을 미치는 모든 검증은 서버에서 진행
3. 일반 비즈니스 Application 서비스의 부하 분산 전략과 게임 아키텍처에서의 부하 분산 전략의 차이점은?
-> 특별히 다를 것 없다. 게임의 기술적 특징에 따라 부하 분산도 사용할 수 있고, 게임 서버 metric에 따라 스케일링이 가능한 게임 전용 관리 플랫폼(GameLift 등)을 사용할 수도 있다.
-> 내부 호출의 부하 분산을 위해 message queue나 service mesh 등을 사용하기도 한다.
-> 보통 최대 플레이어가 제한된 채널(게임 서버)을 플레이어가 선택하도록 한다.
-> 스케일링 중에는 게임 접속을 대기하도록 접속 대기열 방식도 사용한다.
4. 한 번에 여러 플레이어의 요청을 동시에 맞춰서 처리/전송해야 하는 게임의 경우, 플레이어 간 sync를 맞추기 위해 아키텍처에서 어떤 부분을 주의해야 하는지?
-> 네트워크 지연 최소화/유무선 네트워크 환경에 대한 고려/sync에 필요한 전송량/회수 최소화
-> 서버에서 모든 것을 처리하려 들지 말고 플레이어 경험을 해치지 않는 일부 처리는 클라이언트에 넘기는 것도 고려 필요
5. 리플레이를 위해 Starcraft/LoL에서 실시간 스트리밍 영상을 저장하는 기능을 제공하는데, 이 부분은 어떤 구조로 구성해 기능화해야 하는지?
-> 게임 진행 중 발생한 플레이어의 키 입력 등의 입력과 게임에 필요한 메타 정보를 함께 묶어 시간 정보와 함께 저장하고, 해당 정보를 바탕으로 재생(옵저버 모드).
-> 이 이유로 리플레이 파일은 생각보다 작다
6. (Dedicated Server가 아닌) Stateful 한 실시간 멀티 플레이 게임은 어떻게 무중단 배포를 구현하는지?
-> 이전 배포와 호환성이 있는 마이너한 배포의 경우 Rolling update를 고려해볼 수 있다.
-> 해당 서버 종료 시 클라이언트가 재접속하도록 유도(or 자동 재접속)
-> 이 순간을 플레이어가 어떻게 자연스럽게 받아들이도록 할 수 있을지 고민 필요
7. 모바일 게임 플레이어가 일명 '리세마라'를 통해 다수의 정보를 새롭게 등록해 게임 DB가 터지는 경우가 있다고 한다. 어떻게 막아야 할지?
-> 막기보다는 허용하는 것이 낫다. 그런 플레이어들도 없는 것보다는 있는 것이 낫다.
-> 저장량이 너무 많아지는 경우를 대비해 계정 유효 기간 등의 정리 정책 필요.
-> 해당 트래픽이 Abuse(해킹 툴, 봇, 작업장 등)인지 아닌지 분별하고 정리할 수 있도록 서버에서 데이터 검증/안티 치트 솔루션(행동 분석을 통한 비정상적인 동작 감지 등) 도입을 고려해야 한다.
8. 패킷 교환이 많은 게임 서버에서는 어떤 모니터링 툴을 주로 사용해 장애 파악/성능 지표 확인을 할 수 있는지?
-> Grafana/Datadog도 쓰긴 하는데... 모니터링 툴의 문제가 아니라 어떤 metric을 수집하고 관찰할지가 더 중요.
-> load 테스트 등을 통해 필요 metric을 찾아볼 필요가 있다.
9. API라면 Datadog 같은 것을 많이 사용하던데, 소켓 서버는 어떤 방식으로 모니터링해야 할지?
-> 로그를 기록하거나, metric 모니터링 도구에서 제공하는 코드를 소켓 서버에 임베딩하여 원하는 metric을 기록할 수 있다.
-> GameLift에서도 해당 기능을 제공한다 :
https://docs.aws.amazon.com/ko_kr/gamelift/latest/developerguide/logging-server-messages-custom.html
참고할 만한 자료 :
https://www.megazone.com/gamingsales-edm-awsbestarchitecture/
https://www.megazone.com/game-tech-blog-amazon-gamelift/
https://aws.amazon.com/ko/blogs/korea/session-based-game-architecture-in-aws/
https://aws.amazon.com/ko/blogs/korea/web-based-game-architecture-patterns/
'IT 지식' 카테고리의 다른 글
GDPR (0) | 2023.06.10 |
---|---|
CAPEX / OPEX (0) | 2023.06.10 |
Dead Reckoning (0) | 2022.11.28 |
Lag Compensation (0) | 2022.11.28 |
Kafka 입문 (4) (0) | 2022.10.06 |
댓글