[TIL] 게임 서버와 클라이언트 - 게임 서버의 품질 (2)

KYJ의 Tech Velog·2024년 3월 11일
0

성능

확장성과 비슷해 보이지만 다릅니다. 확장성은 사용자가 많아지더라도 서버의 처리 속도가 저하되지 않게 하는 것과 관련된 것입니다. 성능은 얼마나 빨리 처리하는지에 관련된 것입니다.

게임의 종류에 따라 요구되는 성능은 다릅니다. 플레이어가 차례대로 한 명씩 행동을 하는 게임, 예를 들어 보드 게임은 처리 속도가 느려도 괜찮습니다. 한 플레이어의 행동이 다른 플레이어에게 보여지는 데에 1초 정도 걸려도 크게 문제는 없습니다.

FPS 게임의 경우에는 다릅니다. 순간순간의 행동 차이가 총을 맞느냐 안 맞느냐, 죽느냐 사느냐가 결정되는 게임입니다. 0.01초의 차이도 결과를 다르게 할 수 있습니다. 0.05초 이상 걸리는 처리 시간을 용납되지 않을 것입니다.

또한, 플레이어의 행동 종류에 따라 요구되는 성능도 다릅니다. 저격총 관련 처리는 0.01초 차이도 문제를 일으킬 수 있지만, 기관총 근접 전투에서는 0.05초 정도의 차이는 용납되기도 한다고 합니다. 게임 플레이를 하기 전에 매치메이킹 과정과 채팅 과정에서 1초 정도의 차이는 별로 문제가 되지 않습니다. 또한 로그인하는 과정 또한 시간이 몇 초 걸려도 크게 불편해하지 않죠.

다만, 실시간 멀티플레이를 할 때에는 처리 시간에 민감합니다. 처리 속도가 느린 것에 대해 소위 "랙이 있다"라고 말하죠. 랙이 심한 것은 플레이어에게 정말 성가실 겁니다.

성능과 확장성은 연관되는 경우가 많지만, 항상 그런 것은 아닙니다. 전혀 연관이 없을 때도 있습니다. 성능은 좋지만 확장성이 나쁜 경우도 있고, 반대인 경우도 있습니다. 성능만 좋고 확장성이 나쁘면, 게임 사용자 수가 늘어날수록 플레이어의 행동 처리가 완료되는 데 걸리는 시간이 증가합니다. 반대의 경우라면, 사용자 수에 상관없이 처리 시간이 증가할 것입니다.

온라인 게임의 처리 성능은 서버뿐만 아니라 네트워크 환경에 따라 결정됩니다. 서버의 처리가 아무리 빨라도 서버와 클라이언트 사이의 네트워크가 느리면 의미가 없겠죠. 반대도 마찬가지입니다. 서버 성능을 높이기 위해서는 서버의 단위 처리 속도를 높이는 것이 기본입니다. 서버는 클라이언트의 요청 메시지를 받으면 최대한 빨리 처리해서 응답 메시지를 보내줄 수 있어야 합니다.

서버의 단위 처리 속도를 높이려면 프로그램이 더 빨리 실행될 수 있도록 소스 코드 최적화나 알고리즘 최적화를 해야 합니다. 예시로 RPG 게임에서는 길찾기 알고리즘이 소요하는 처리 시간을 O(1)로 개선하고자 path table 테크닉을 쓰기도 하죠.

실행 속도가 빠른 프로그래밍 언어를 활용할 수도 있습니다. 실제로 많은 실시간 멀티플레이 게임에서는 파이썬이나 자바보다는 C++를 사용합니다. 좋은 서버 하드웨어를 쓰는 것도 방법입니다.

과부하 영역을 분산하는 것도 서버 성능을 높일 수 있습니다. 게임 서버뿐만 아니라 일반적인 프로그램의 처리 속도를 높이고자 먼저 해 보는 방법 중 하나는 코드 프로파일링을 활용하는 것입니다. 어떤 함수가 처리 시간을 많이 차지하는지 확인하고 거기에 집중해서 성능을 개선하는 것이죠. 만약 특정 함수의 처리 시간을 개선할 수 있는 방법이 더 없고 실행 빈도도 줄일 수 없다면 분산을 해야 합니다. 그 함수를 다른 컴퓨터에서 실행하게 하면 문제를 해결할 수 있습니다.

플레이어가 느끼는 처리 성능을 높이는 또 다른 방법은 네트워크 프로토콜을 최적화하는 것입니다. 네트워크 프로토콜 최적화의 첫 번째 방법은 메시지의 양을 줄이는 것입니다. 서버는 송수신해야 하는 메시지 수가 많거나 메시지가 차지하는 총량(바이트 수)이 많으면 처리 부담이 증가합니다. 메시지를 압축하는 방법으로 메시지의 양을 줄일 수 있습니다. 수 킬로바이트 이상의 텍스트 데이터에서는 데이터 ZLib를 이용한 압축과 같은 무손실 알고리즘이 잘 작동합니다. 하지만 실시간 멀티플레이 게임의 대부분의 데이터는 플레이어 이동과 관련된 것인데 이는 크기가 수십 바이트 정도로 작은 데다 압축 여지가 있는 패턴을 이루지 않아 압축 효과가 별로 없습니다. 그 때 사용하는 다른 압축 기법이 바로 양자화입니다.

양자화는 정수 혹은 부동소수점 값의 정밀도를 낮추는 대신 값이 차지하는 데이터 크기를 줄이는 방법입니다. 플레이어의 체력 값이 0~100으로 제한되고 소수점 값 정밀도가 0.5까지 오차가 있다고 가정해봅시다. 2를 곱하면 정수 0~200으로 원하는 정밀도 값을 유지할 수 있습니다. 0~200의 값은 1바이트로 표현할 수 있으므로 플레이어의 체력은 1바이트로 줄일 수 있습니다. 네트워크로 주고받을 때만 1바이트로 줄이고 게임 프로그램 안에서는 부동소수점 값으로 가지고 있어도 상관없습니다.

네트워크 프로토콜 최적화의 또 다른 방법은 메시지 교환 횟수를 줄이는 것입니다. 서버와 클라이언트 간의 메시지 교환 횟수가 늘어날수록 처리 시간도 늘어나게 되겠죠. 주고받는 과정을 몇 초 사이에 여러 번 반복하는 상황이라면 한 번에 송신하고 한 번에 수신하면 교환 횟수를 줄일 수 있습니다.

서비스 성능을 개선하려면 네트워크 전송 시간을 줄이는 것도 효과적입니다. 고품질 네트워크 회선을 가진 데이터센터에 서버를 설치하면 전송 시간을 효과적으로 줄일 수 있습니다. 물론 비용이 많이 들겠죠.

지리적으로 가까운 데이터센터에 서벋들을 분산해서 설치하는 것도 좋습니다. 실제로 많은 게임 이 서비스를 채택한다고 하네요. 물론 함께하는 플레이어 간의 물리적 거리가 너무 멀다면(만약 지구 반대편) 의미가 없긴 합니다. 이를 최소화하고자 반강제로라도 지리적으로 가까운 플레이어끼리 함께 플레이하도록 유도하는 것이 좋습니다.

서버를 거치지 않고 클라이언트끼리 통신하게 하는 것도 방법입니다. 이를 P2P 네트워킹이라고 합니다. 클라이언트 간의 레이턴시보다 서버와 클라이언트 간 레이턴시가 긴 경우에 효과적인 방법입니다. 특히 0.01초의 차이가 큰 영향을 주는 FPS에서 자주 사용되는 기법이죠. 서버에 걸리는 부담도 줄여줄 수 있습니다. 그래서 파일 전송이나 음성 및 화상 채팅처럼 클라이언트 간 주고받는 데이터의 양이 클 때 더욱 효과적입니다. 하지만 단점도 존재합니다. 서버가 주고받는 메시지 검증을 할 수가 없습니다. 클라이언트가 해킹 당하면 문제가 되겠죠. 또한, 현재 컴퓨터 네트워크에서는 인터넷 공유기 같은 NAT 라우터를 많이 사용하곤 하는데 일부 라우터에서는 클라이언트 간 데이터를 주고받을 수 없어 데이터를 중계, 즉 릴레이 해주는 서버가 있어야 할 경우도 있다고 합니다.


관리 편의성

일반적인 게임 서버는 콘솔 프로그램 형태로 작동합니다. 서버 프로그램은 거의 사용자 입력에 직접 상호 작용하지 않죠. "프로그램을 끈다."가 유일한 직접 상호 작용 기능입니다.

실제 서비스 운영을 할 때는 백그라운드 프로세스로 실행시키기도 합니다. 심지어 서버 컴퓨터를 부팅한 후에 사용자 로그인을 하지 않아도 자동으로 실행하게 만들기도 합니다. 운영체제에 서버 프로그램을 등록해주면 로그인 없이도 자동 실행되게 할 수 있습니다.

이처럼 등록된 백그라운드 프로그램을 윈도우 서버에서는 서비스라고 합니다. 리눅스 등 유닉스 운영체제에서는 데몬이라고 합니다.

서비스나 데몬은 프로그램 종료 같은 극히 제한적인 종류의 명령만 처리할 수 있습니다. 백그라운드에서 실행되고 있기 때문에 GUI는 물론이고 콘솔에 텍스트를 출력하면 화면에 아무것도 나타나지 않죠.

결국 데스크톱에서 이들을 제어할 수 있는 것은 켜고 끄는 것 외에는 거의 없습니다. 이러한 서버를 관리하기 위해서 가장 많이 사용하는 방법은 원격으로 관리하는 프로그램을 따로 이용하는 것입니다. 서버 프로그램과 네트워크 통신을 하는 별도 프로그램을 두고, 그 프로그램에 필요한 사항을들을 자유롭게 설정해놓는 것이죠. 이를 관리 도구 혹은 운영 도구라고 합니다.

관리 도구는 GUI 앱, 콘솔 프로그램, 웹앱 등 다양한 형태를 가집니다. 자유롭게 원하는 기능을 만들 수도 있죠. 필수로 하는 기능을 다음과 같습니다.

  • 서버 켜기/끄기
  • 동시접속자 수 보기
  • CPU, RAM 사용량 보기

관리 도구는 게임을 운영하는 조직이 클수록 역할이 분담됩니다. 실수나 의도적인 사고를 막기 위해 사용자에 따라 일부 기능이 제한되게 만들기도 합니다. 예시로 게임 운영자는 서버를 켜고 끌수는 없지만 플레이어에 대한 제재를 할 수 있는 관리 도구가 주어집니다. 서버 관리자는 서버를 켜고 끌수 있는 관리 도구를 사용합니다.

0개의 댓글