Extra Form

 

게임 서버 엔진 개발사 넷텐션의 배현직 CTO가 지스타 2021 게임 컨퍼런스에서 게임서버 개발 방법에 관련된 강연을 진행했다. 이날 강연은 프로그래머가 아닌 프로그래머와 함께 일하는 실무자에게 도움이 될만한 내용으로 구성되어 주요 게임 장르별 서버 아키텍처 소개, 서버에 발생하는 문제의 종류와 그 원인, 서버에 발생하는 문제의 해결 방법에 대해 소개했다.

 

배현직 CTO는 "실무자들이 프로그래머와 커뮤니케이션을 할 때도 소통이 잘 되는 대화 도구를 가져간다면 오늘 발표가 뿌듯할 거 같다."라며 발표를 시작했다.

 

output_3887188440.jpg

▶ 넷텐션 배현직 CTO

 

그는 먼저 일반적인 서버 아키텍처를 게임 장르별로 소개했다. 게임 서버 아키텍처는 정해진 형태가 없으며, 게임의 형태나 어떤 콘텐츠를 쌓는지에 따라 달라진다. 모바일 RPG는 모바일 기기(클라이언트)가 '로드 밸런서'로 접속한 뒤 다수의 게임 서버 기기를 모은 '게임 서버 클러스터' 중 하나로 접속한다. 게임 서버 클러스터는 클라이언트와 신호를 주고받으며 저장한 결과를 인메모리 캐시 클러스터와 데이터베이스 클러스터에 나눠 저장한다. 인메모리 캐시 클러스터에는 현재 플레이어의 상태를, 데이터베이스 클러스터에는 영구적으로 저장해야 하는 데이터가 저장된다.

 

로드 밸런서는 다수의 클라이언트로부터 오는 요청을 분산시켜 서버의 부담을 줄이는 역할을 하는데, 일반적인 모바일 RPG에서는 뽑기나 강화에서 버튼을 누르고 결과가 나오기까지 1초가 더 걸려도 괜찮기에 로드 밸런서를 사용한다. 다만, 전투 장면처럼 빠른 반응속도가 중요한 경우에는 서버와 실시간으로 접속하지 않도록 해 반응속도를 확보한다고.

 

output_1594681893.jpg

 

MO게임은 아웃 게임서버 클러스터와 인게임 서버 클러스터가 나뉜다. 인게임 서버 클러스터는 실시간 멀티플레이 전투를 담당하고, 아웃게임 서버 클러스터는 전투 외의 모든 것을 처리한다. 매치 메이킹은 게임 밸런스에 영향을 주는 부분으로, 게임 기획이나 서비스 오픈 후 유지 과정에서 업데이트를 하는 과정에서 프로그램이 복잡해지고 유지보수가 어려워진다. 아웃게임 서버 클러스터는 앞서 소개한 모바일 RPG의 구조와 비슷하나, 인게임 서버 클러스터는 로드 밸런서를 거치지 않고 직접 접속해 빠른 반응속도를 확보한다. 또, 인게임 서버 클러스터는 렉이 생기지 않도록 하는 게 중요하기에 여러 국가(리전)에 서버를 분산해 배치한다.

 

DSC00172.jpg

 

그리고 MMO게임은 다수의 존 서버 클러스터를 구성한다. 인게임 서버 클러스터와 구성이 비슷하지만, 존1, 존2, 존3.. 여러 서버로 나뉘며 클러스터화되어 작동한다. 존 서버 역시 미국과 중국, 일본 등 서로 다른 리전에 서버 클러스터를 배치한다.

 

배현직 CTO는 "여기서 소개한 게임 서버 아키텍처는 극히 단순화한 것으로, 인앱결제, 로그인 통합, 비즈니스 인텔리전스, 운영 등이 들어가면 서버 구조가 더 복잡해진다."라고 덧붙였다.

 

DSC00173.jpg

 

다음으로는 서버 크래시와 서버 무응답, 렉, 오버 오동작, 해킹 등 게임 서비스 진행 중 발생하는 서버 문제의 종류에 대해 소개했다.

 

서버 크래시는 이름 그대로 서버가 죽는 것이다. 서버 역시 프로그램이기 때문에 프로그램 안에서 건드리면 안 되는 영역의 데이터를 잘못 건드려 그래도 프로그램이 죽어버린다고 한다. 클라이언트에게는 서버 연결이 끊어졌다는 형태로 에러 메시지가 나오며, 이 경우에는 서버 팀에서도 즉각적인 문제 인식이 가능하다고 한다.

 

서버 무응답은 서버가 클라이언트로부터 오는 요청을 처리해 주지 않는 상황으로, 흔히 서버가 얼어버렸다(프리징)라고 표현한다. 서버 무응답에는 여러 이유가 있는데 가장 까다로운 타입은 서버가 요청을 처리하는 속도보다 클라이언트의 요청이 훨씬 많은 경우다. 이 경우에는 캐릭터나 NPC가 멈추거나, 모션이 고정된 채 가던 방향으로 계속 이동하는 등의 문제가 발생한다. 서버팀에서는 이를 미리 파악하는 경우도 있지만 한순간에 갑자기 요청이 몰려 서버가 무응답 상태가 돼 뒤늦게 파악하는 경우도 있다고 한다. 그래서 서버 무응답은 크래시보다 해결 난이도가 높다고 한다.

 

IMG_1879.jpg

▶ 서버 무응답 상황에서 벌어지는 대표적인 현상인 '모내기 버그'

 

렉은 서버 무응답과 동일하게 서버가 요청을 처리하는 속도보다 클라이언트의 요청이 많은 경우에 발생하는데, 무응답과 다른 점이 있다면 클라이언트의 요청이 많아졌다 적어졌다를 반복한다는 것이다. 렉은 서버 내부 문제보다는 망이 문제가 될 때도 있다. 클라이언트와 서버 간 망 레이턴시가 너무 길거나, 매치메이킹 시스템에서 가까운 리전의 서버가 아니라 먼 리전의 서버가 매칭됐을 때 망 자체가 상대 서버까지 도달하는 시간이 길어져 렉이 발생하기도 한다. 렉은 서버 크래시나 서버 무응답보다는 심각성이 덜하지만, 방치하면 고객 만족도가 떨어진다.

 

서버 오동작은 서버의 요청 처리 속도에는 문제가 없지만, 뭔가 요청했을 때 이상한 결과를 출력하는 현상이다. 아이템 교환 시 아이템이 누락되거나, 나와야 할 아이템이 나오지 않는다거나, 특정 행동을 할 때마다 아이템이 복사된다거나 하는 것이 대표적이다. 서버 오동작이 심각한 것은 유료 아이템에서 관련 문제가 발생했을 때, 그리고 게임의 상태가 적게는 2~3분 전, 길게는 30분 전으로 돌아가는 '백섭'이다. 유료 아이템을 구입했는데 게임을 끄고 다시 들어와 보니 사기 전의 상태로 돌아가있다면 운영팀도 함께 로그를 추적하며 사태가 복잡해진다. 이런 서버 오동작은 서버 개발자의 실수로 일어나는 경우가 많다. 코딩을 잘못했거나 테스트가 부족했을 경우다. 또, QA팀과 서버 개발팀이 최선을 다했음에도 서버의 구조가 너무 복잡하면 서버 오동작이 나기도 한다. 서버를 수평 확장적 구조로 설계했을 때가 대표적이다.

 

DSC00183.jpg

▶ 디아블로의 아이템 복사는 서버 오동작을 이용한 버그라고

 

서버를 완벽하게 만들면 아무런 문제도 없을까? 아니다. 서버를 아무리 완벽하게 만들어도 해킹으로 인해 문제가 발생할 수 있다. 서버 개발자는 해킹이 얼마나 들어오든 막을 수 있어야 하는데, 이론적으로 모든 해킹을 막으려면 클라이언트가 하는 일을 모두 서버로 옮기면 된다. 하지만 그러면 동시 접속자 수 3,000명을 수용하는 서버가 300명밖에 수용하지 못하게 돼 서버 유지 비용이 크게 증가하고, 인터넷 품질이 조금만 나빠져도 게임 플레이에서의 불편함이 크게 늘어난다. 서버 개발자는 모든 설계에서 항상 해킹 가능성을 차단하되, 비용 문제에서는 양보할 수밖에 없다. FPS에서 제일 찾기 힘든 핵이 에임핵이다. 비용 문제로 서버에서 막지 않고 핵실드 같은 멀웨어 차단 프로그램을 사용해 클라이언트에서 막는다. 유저 입장에서는 불편할 수 있지만, 에임핵 처리를 서버에서 하면 인터넷이 조금만 느려져도 너무 느려서 게임을 하기 힘들다.

 

DSC00185.jpg

▶ 해킹의 대표적인 예시인 맵핵

 

그리고 이러한 서버 문제는 게임 개발 일정에 영향을 주기도 한다. 왜일까? 먼저, 서버는 테스트를 충분하게 할 수 없다. 1차로는 사내 테스트를 진행하고, 서버 과부하 등 동시 접속자 수가 높을 때 생기는 문제를 확인하기 위해서는 매크로 봇을 만들어 테스트한다. 개발 초기에는 매크로 봇만으로도 많은 버그와 서버 성능 문제를 사전에 찾아서 해결할 수 있지만, 사람이 하는 창의적인 행동을 할 수 없어 QA팀이 필요하다. QA팀은 사람이 상상할 수 있는 온갖 행위를 해보고 봇 테스트 시나리오를 구축하지만, 실제로 게임 서비스를 시작하면 QA 영역을 넘어가는 유저가 금방 나온다. 서버는 이처럼 충분한 테스트를 하기 어려워 게임 개발에 지연을 준다.

 

또, 서버는 클라이언트에 비해 문제가 발생했을 때의 파장이 크다. 클라이언트에 문제가 생기면 해당 클라이언트에만 문제가 발생하고, 서버에서는 해당 클라이언트에서 문제가 발생했다는 리포트를 많은 사용자로부터 주기적으로 수집해 해결할 수 있다. 하지만 클라이언트에서 서버에 문제를 일으킬 수 있는 행동을 한다면, 이 문제는 다른 클라이언트에도 모두 영향을 준다. 리포트 역시 한꺼번에 몰려온다. 그래서 서버는 더욱 신중하게 개발 및 테스트를 해야 한다.

 

DSC00192.jpg

▶ 왼쪽은 윈도우, 오른쪽은 리눅스의 서버 화면. 보기만 해서는 알 수 없다.

 

문제의 원인을 찾기 어렵다는 것도 주요 원인 중 하나다. 클라이언트는 문제가 발생하면 화면에 바로 표시돼 오류가 나도 즉시 알 수 있고, 디버그 툴을 사용하면 버그나 난 원인을 바로 추적해 프로그램을 수정할 수 있다. 이후에는 클라이언트를 껐다 다시 키면 끝난다. 재부팅을 해도 해당 클라이언트만 재부팅될 뿐이지 다른 이에게는 영향을 주지 않고, 유저 정보 역시 서버에 저장돼 재부팅을 해도 데이터가 사라지지 않는다.

 

반면, 게임 서버는 화면에 아무것도 보여주지 않는다. 서버가 다운돼도 화면에 나오는 게 아무것도 없다. 그래서 서버 개발자는 모니터링툴을 만들거나 알려진 모니터링 솔루션을 활용하는데, 아무래도 한계가 있다. 클라이언트에 사용하는 디버그 툴을 사용하는 것도 어렵다. 서버에 디버그 툴을 사용하는 순간 서버가 멈춰 접속된 클라이언트의 게임 플레이가 모두 멈추기 때문이다. 디버그 툴을 붙이는 건 사내 개발에서만 가능한 일이다.

 

그래서 서버 개발자는 다른 길을 택한다. 서버에서 발생하는 사소한 이벤트를 전부 기록하는 로그를 남기는 것이다. 문제 해결을 위해서는 로그를 검색해야 하는데, 능숙한 필터링 스킬이 있는 개발자라면 빠르게 로그에서 빠르게 문제를 찾아내 해결할 수 있다. 로그 내용이 디테일하면 서버 처리 속도도 하락하고 그만큼 로그도 많아져 개발자가 로그에서 문제를 찾아내는 일은 더욱 힘들어지지만, 서버 개발자에게는 이게 최선이다.

 

DSC00195.jpg

 

다수의 클라이언트를 커버하기 위해 서버 수를 늘리는 것을 '수평 확장'이라고 하는데, 단일 서버보다 설계가 훨씬 복잡해 문제가 발생했을 시 게임 개발 일정에 영향을 주기도 한다. 버그의 범위가 넓어져 버그를 찾기 힘들뿐더러, 서버 부하를 줄이기 위해 추구한 수평 확장이 오히려 과부하를 일으키기도 한다. 예를 들어, 서버 클러스터를 구성하는 수많은 클러스터 중 문제가 발생한 한 대가 서버 전체를 모두 죽여버리는 '단일 실패 지점'이 대표적이다. 서버 개발자는 단일 실패 지점이 가급적이면 없도록, 있어도 서버 전체가 죽지는 않도록 해야 하지만 이것도 쉽지 않은 일이다. 서버 대수만 늘린다고 해결되지 않는 경우도 있기 때문이다. 그래서 서버를 설계할 때는 무조건 완벽하게 설계하는 걸 목적으로 두기보다는 어느 정도 절충을 할 필요가 있다.

 

로그를 정리하거나 서버 문제를 수정하기 위해서는 서버를 껐다가 다시 켜야 한다. 그래서 점검 시간이 필요하다. 어떤 게임들은 서버를 순차적으로 업데이트하는 롤링 업데이트를 도입하기도 하는데, 해당 서버가 동시 접속자 수가 0명이 될 때까지 기다려야 해서 오랜 시간이 걸린다. 소수의 존에 다수의 유저가 붙어 있는 MMO게임에 적용하기 어렵다는 것도 문제다.

 

서버와 관련된 문제를 소개한 배현직 CTO는 이러한 문제를 원활하게 해결할 수 있는 방법을 전수했다. 앞서 이야기한 것처럼 서버 개발자와 소통하는 실무자를 위한 내용이었다.

 

먼저, 서버팀이 불필요한 요소가 무엇인지 자각하도록 돕는 것이다. 서버팀이 서버 설계를 단순화하도록 여러 가지 리미트 요소를 최대한 알려주는 게 좋다. 그러면 불가피하게 수평 확장 서버 설계가 나올 수밖에 없을 때도 추가 요구 사항에 대응하기 위해 이유가 있는 수평확장 서버 설계가 가능해진다고.

 

또, 서버 개발자가 크고 아름다운 서버 설계를 했을 때는 서비스 시작 시점에 문제가 터질 수도 있다. 이때는 서버팀에게 라이브 서비스가 시작된 뒤에 터질 문제를 빠르게 추적할 스킬을 갖추고 있는지, 그리고 문제 해결을 위해 어떤 툴을 가지고 있는지 확인해야 한다. 만약 서버팀이 지나치게 낙관적이거나 거기까지 생각해 보지 않았다고 하면 위험할 수 있다.

 

DSC00201.jpg

 

DSC00202.jpg

▶ 서버가 복잡할 경우, 서버 개발자에게 서버 설계를 왜 이렇게 했는지 물어보고, 자세한 사양을 다시 전달해 서버를 보다 간결하게 설계된 예시.

 

이어서 배현직 CTO는 서버팀을 위한 툴로 프라우드넷2를 소개했다. 넷텐션의 게임 서버 엔진 '프라우드넷'의 후속 엔진으로, 게임 개발을 하며 부딪히는 여러 문제를 빠르게 찾고 해결하는 도구를 제공한다. 서버에 디버그 툴을 붙이기 어려우니 디버그 트레이서를 붙여 서버가 꺼지지 않도록 했고, 서버에서 디버그를 해야하는 프로그램 시작 지점에 포인트를 찍은 뒤, 서버가 구동되는 도중에 그 지점을 실행할 때마다 로그를 남겨 서버에서 어떤 일이 있었는지를 디버그 툴 수준으로 상세하게 보여준다.

 

'서버메모리 듀얼'을 통해 게임 서버 내에 메모리 내용을 디버그 툴 수준으로 상세하게 열람할 수 있다. 최적화를 거쳐 서비스에 영향을 주지 않도록 했다. 이를 통해 서버 개발자가 라이브 서버에서 무중단 상태에서 서버에 큰 부하를 주지 않고 실시간으로 문제를 찾아나갈 수 있다.

 

여기에 성능 분석 기능도 있어서 서버 내 어떤 지점이 성능을 많이 차지하는지 확인할 수 있다. 흔한 서버 부하 모니터링부터 서버 내에서 프로그램이 어디에서 성능을 많이 먹는지도 추적이 가능하다. 크래시 리포트 기능도 있어 크래시 난 서버를 자동 재시작하며 어디서 문제가 생겼는지 바로 확인할 수 있다.

 

서버팀이 문제를 해결한 뒤 패치할 때를 위해 핫 리로드 기능을 지원한다. 플레이어가 접속한 상태에서 서버를 바로 수정하는 것으로, 점검 업데이트, 롤링 업데이트의 단점을 극복하고 다수의 서버를 한꺼번에 업데이트할 수 있는 것이 특징이다.

 

서버 개발자가 멀티플레이 동기화에서의 코딩 노가다를 줄여주는 동기화 코드 자동 생성 기능도 추가됐다. 편리한 것도 있지만, 중요한 것은 잘못된 코딩을 줄여 실수의 여지를 줄인다는 것이다. 배현직 CTO는 "서버 안정화는 대단한 게 필요치 않다. 단순해야 한다. 쉬워야 한다. 그게 중요한 패턴 중 하나"라고 강조했다.

 

이런 여러 기능은 서버 클러스터 전반적으로 모니터링과 컨트롤이 가능하다. 성능 분석 기능은 한 서버는 물론 100대, 200대의 서버를 취합해 전체의 성능을 한 대처럼 합쳐서 보는 것도 가능하다. 다른 툴 역시 마찬가지로, 이를 이용하면 다수의 서버가 있을 때 빠르게 문제의 원인을 찾아내고 해결할 수 있다.

 

DSC00205.jpg

 

끝으로 배현직 CTO는 "프라우드넷이 나온지 10년이 됐다. 게임 서버 개발자들의 여러 어려움을 해결해 줬다. 프라우드넷2는 복잡한 서버 콘텐츠 개발에서 발생하는 어려움을 해결해 주는 것이 목표다."라며 발표를 마무리했다.

 

DSC00209.jpg

 



댓글 0
댓글 쓰기 권한이 없습니다.
1 - 70