게이머들이 가장 싫어하는 것 중 하나는 소위 3대 명검이라 불리는 '긴급/연장/임시 점검'이지 않을까 한다. 그리고 갑작스레 찾아오는 점검의 마수는 게이머뿐만 아니라 개발자들에게도 날벼락 같은 소식이다. 점검한다는 것은 결국, 큰 문제가 발생하여 수정해야 할 것이 생겼다는 의미기도 하니 말이다.

그렇다면 이런 문제들을 조기에 찾아낼 수는 없을까? 왜 문제는 항상 갑작스레 터져 나오는 것일까? 현재 분석개발팀에서 개발하고 있으며, 한 때 '마비노기 영웅전' 서버 프로그래머와 라이브 매니저 업무를 맡았던 이영득 개발자는 이에 문제를 제기하고 해결하기 위한 노력을 진행했다.

마영전 서버 프로그래머로 근무하며, 버그와 문제 파악을 위해 수많은 시도를 했었던 이영득 개발자는 자신이 경험했던 해결 사례들을 정리했다. 그리고 이를 NDC2017의 마이크를 통해 전달하려 한다.

▲ 넥슨코리아 분석개발팀의 이영득 개발자

일반적인 라이브 서비스는 물리적으로는 유저의 컴퓨터가 서버에 접속하고, 개발자는 개발 환경에 접속하며, 특정 주기마다 라이브 서버로 업데이트하는 방식을 취한다. 강연자는 이 중에서 서버 그룹과 개발 환경에 관해서 이야기한다고 밝혔다.

본격적인 강연 시작 전, "혹자는 '아니!? 마영전 개발자가 서버 안정성을 논한다고?'라는 말을 할지도 모른다"고 언급했다. 그만큼 말도 많고 탈도 많았던 이야기이며, 이번 강연에서는 서버 문제를 해결하기 위해서 노력했던 일들을 정리하고자 했다고 전했다.

이영득 개발자는 마영전 서버프로그래머이자 라이브 매니저 업무를 진행 중이던 어느 날, 기회가 문득 찾아왔다고 회상했다. 그리고 막상 해결하려던 차, 고민에 빠지게 됐다. 당연히 안정적인 서비스를 추구해야 했지만, 지금까지의 경험으로는 안정적인 서비스를 위해서는 비용과 사람, 시간이 필요했다. 어느 쪽을 선택해야 할지가 문제였다.


강연자는 이미 만들어진 구조를 개선하려는 방법을 고민하기 시작했다. 뭐가 문제이며, 어떻게 이슈들을 해결할 수 있는지. 하나를 수정하면 오래 묵은 코드들이 문제를 발생시키기도 하는 라이브 게임 개발과 배포에서 효과를 봤던 해결법들을 청중에게 전달하고자 했다.



■ #1 - 기록하고 공유하기

먼저, 장애가 발생하면 원인을 추적하고 해결하고 정리하려 했다. 하지만 이런 프로세스는 노하우 공유가 어렵고, 유사한 문제를 다른 사람이 다시 하는 경우까지 있었다. 결국, 서로의 경험이 기록 및 공유되지 않기 때문에 발생하는 문제였다.

강연자는 이를 위해서 점검 보고서를 작성하고 데이터를 축적하기 위해 노력했다. 긴급, 연장, 임시 점검 시 사후에 작성하는 것을 기준으로 삼았으며, 있는 사실만 기록하고자 했다. 작성한 점검 보고서는 각 국가의 담당 개발/PM, 프로젝트 매니저 그룹에게 메일로 발송했다. 하나의 브랜치에 버그가 있다면, 다른 국가에도 있을 가능성이 높았기 때문이다.

이렇게 장애 기록을 보존하는 것은 같은 문제 발생 시에 히스토리 로그로 이용되었다. 추후 예방을 위한 고민을 유도하는 장치로도 사용되었으며, 다른 국가에서 같은 문제가 발생하지 않도록 사전 인지하는 효과가 있었다.

결과적으로 문제의 원인이 어디에 있는지 파악하게 되었으며, 환경 개선 작업의 우선순위를 산출하기 위한 근거로도 활용할 수 있었다. 강연자는 이러한 일련의 과정으로 통해 '점검의 횟수는 큰 의미가 없으며, 문제는 이슈가 얼마나 발생했느냐'에 초점을 두게 되었다고 밝혔다. 또한, 이슈는 장기적인 관점에서 바라보는 것이 중요하며, 기록을 남기는 것이 나중에 얻는 효과가 더 크다는 점을 느꼈다고 전했다.




■ #2 - 덤프 마스터가 필요해!

다음으로는 원인을 파악하는 과정으로 넘어갈 차례였다. 하지만 개발 규모가 작을 때처럼 가설을 세우고 이를 수정 및 배포하는 것은 불가능했다. 마영전은 2~3개의 국가에만 서비스되는 것이 아니라, 7개 국가에 서비스 중이며 4~6주간 개발한 리스트가 150개 가량 되었기 때문이다. 이를 하나씩 보기에는 시간이 너무도 많이 필요한 상황이었다.

그래서 '덤프'로 해결하는 것을 기조로 삼았다. 당시 마영전은 크래시를 파악할 수 있는 자료가 없어, 도구를 찾고 적용하는 단계부터 시작했다. 몇 개의 분석 도구를 비교하여 덤프를 위한 도구를 찾았고, 이를 서버에 적용하는 데까지 진행했다.

게임 규모가 커질수록 크래시나 메모리 릭처럼 명확한 문제들이 발생하기 마련. 이럴 때에는 덤프를 열어보고, 적용하는 것으로 결정했다. 툴의 사용법을 배우는 것이 생각보다 어렵지 않으며, 짐작과 예측으로 라이브에 수정점을 패치하는 것은 위험하다는 판단에서다.

라이브에 수정점을 패치한 것이 잘못되었을 때는, 다시 한 번의 긴급 점검을 해야 한다는 맹점이 존재했기 때문이다. 강연자는 청중들에게 이와 같은 점을 설명하면서, '한 번의 시도가 한 번의 긴급 점검을 의미한다'고 다시금 강조했다. 정확한 정보에 근거해서 수정을 해야 한다는 의미이기도 하다.




■ #3 - 응답속도 정보 모으기

흔히 말하는 '랙'이 문제가 되기도 했다. 강연자는 '랙'의 원인에는 유저의 네트워크 환경과 같은 변수가 많으므로 특정짓기가 어렵다고 말한 뒤, 상세 정보의 획득이 어렵다고 알렸다. 그리고 다양한 변수 탓에 발생하는 것이 랙이므로, 문제 때문에 강연에서는 서버랙으로 범위를 한정 지어 설명을 시작했다.

마영전의 서버는 분산 아키텍처로 구성되어 있고, 서비스 종류가 10개 이상, 프로세스의 개수는 300개 정도에 이르렀다. 하나의 머신에 5~10개의 프로세스가 구동되는 형태라, 어떤 서비스가 느리다 빠르다를 판정하기가 어려운 구조였다. 그래서 랙을 파악하기 위해서는 이를 판단하기 위한 데이터와 작업 처리가 필요했다.

강연자는 지연이 처리량 오버된 상태에서 발생하는 것으로 판단하고 자료를 수집했다. 데이터를 기반으로 문제의 범위를 파악하고, 세부적인 패킷 단위로 분석했다. 문제점이 있는 패킷을 확인한 뒤에는 구간 튜닝에 들어갔다. 하지만 한 번의 작업으로 모든 국가에 대응하는 것은 어려웠다. 데이터 보관 장소가 국가마다 달랐기 때문이다.

그래서 데이터를 같은 IDC 안에 축적하는 것으로 개편했다. 개발자는 웹 서버에만 접근해서 각 국가의 지표를 확인할 수 있고, 문제점을 통합해서 확인할 수 있었다.




■ #4 - 실시간 제어 기능

어떠한 문제점이 발생했을 때, 실시간으로 수정할 수 있게 해달라는 요구가 나오기도 했다. 콘텐츠 이용을 막는 한이 있더라도, 서버만을 살려야 하면 필요한 기능이었다. 하지만 마영전은 실시간 패치가 어려운 프로세스 구조라는 것이 문제가 됐다.

이는 개발 시에 기능별로 On/Off 할 수 있는 옵션을 추가하는 것에서 답을 찾았다. 실시간 제어 기능은 문제 확산 여지가 있는 경우와 프로파일링 작업을 한시적으로만 진행할 때 유용한 기능이었다. 하지만 테스트를 적어도 두 번 이상 해야하고, 기능 사이에 의존성이 있을 때에는 치명적일 수 있는 문제가 발생했다.

강연자는 운영 툴에서 명령을 입력하는 것으로 문제를 막아낼 수 있는 편리한 기능이지만, 한편으로는 위험한 방법의 하나라고 청중들에게 당부의 말을 남겼다. 스펠링 오류가 나는 것만으로도 데이터 전체가 꼬일 수 있기 때문에 검수에 많은 인력과 시간이 필요하기 때문이다.




■ #5 - 코드 리뷰

문제가 어디서 발생했는지를 파악했다면, 이제는 근본적인 생산지를 없앨 차례다. 강연자는 팀장의 '당연히 개발하니까 문제가 생긴다'는 농담에서 깨달음을 얻었다고 전했다. 배포된 버전은 결국 누군가 개발한 것이고, 컴퓨터와 코드는 거짓말을 하지 않는다는 생각이 들었다고 전했다. 어차피 문제가 발생한다면? 이를 조기 발견으로 해결하고자 했다. 그래서 도입하기 시작한 것이 '코드 리뷰'다.


도입 과정에서 많은 내적 갈등도 있었으나, '해보고 정하자'는 일종의 실험 느낌으로 진행했다고 밝혔다. 코드를 일부 작업만 선정하고 혼자서 리뷰하는 방식과, 툴을 이용해서 커뮤니케이션 하는 방식 등을 적용하기도 했다. 하지만 일장 일단이 있어 '리뷰 보드'라는 라인 단위로 코멘트를 할 수 있는 툴로 정착됐다.

강연자는 이와 같은 코드 리뷰를 거치면, 완성도가 늘어나는 장점이 있다고 설명했다. 개발자들이 서로 코드 퀄리티에 대한 이야기들로 성장하는 효과도 가져왔다. 발생할 수 있는 리스크는 조기 진단할 수 있으므로, 전반적인 안정성도 찾을 수 있었다. 하지만 시간과 정성적인 관점에서 10~20% 정도의 추가 업무가 발생한다는 것은 기억해야 한다고 알렸다.




■ #6 - 문제의 인지 시점 당기기

이후 단계로는 문제의 인지 시점을 앞당기기 위한 절차를 진행했다. 프로그래머 직군에 한정하여 배포될 때까지의 단계를 잘게 쪼갰다. 그리고는 언제 알 수 있느냐를 고민하기 시작했다. 배포용 클라이언트를 생성할 때 사용하는 이그노어 리스트(IgnoreList)가 대표적인 문제 사례가 됨을 확인했다.

배표용 클라이언트를 생성하고 나서 문제가 감지되고, 이를 수정하여 업로드 하는 데에만 1시간이 걸렸다. 문제 발생 후 재패키징을 했을 때, 종종 연장 점검되는 사례로 이어졌던 것이다. 강연자는 이를 '제외될 파일이 로딩되려는 시점에 에러창을 띄우는 방법'으로 간단하게 해결할 수 있었다.

문제가 발생할 수 있을 때 에러창을 출력하는 것으로 강제를 시켰다. 심지어 10개의 소스가 잘못 들어가 있다면, 10번을 눌러야 하는 형태였다. 이로써 기획자 PC에서 로컬 서버를 띄우는 것도 가능해졌으며, 빌드 머신에서 무결성 체크 로직을 추가하는 형태로도 이어졌다.




■ #7 - 마지막으로, 대화하기

강연자는 강연을 정리하면서 '버그가 있다는 것을 인지하는 시점이 어디인지 파악'하는 것이 중요하다고 강조했다. 인지 시점을 더 빠른 단계에서 확인할 수 없는지 고민해야 하며, 이를 어떻게 해결할 수 있을 것인지 절차 또한 고민해야 한다고 알렸다.

결국, 개발 환경의 사용자는 개발팀이기 때문에, 사용자의 기호와 편의에 맞게 기능을 제공하는 과정이 필요함도 필요하다고 전했다. 이를 위해서는 양측의 의견 수렴이 필요하며, 업무 전반에 들이는 노력과 시간을 줄일 수 있는 가치있는 일이라고도 언급했다.

마지막으로 강연자는 자신의 마영전 라이브 서비스 경험에 비추어 봤을 때, 문제 해결에는 지속적인 관심이 필요하며, 주변에 있는 도구가 중요하다고 강조했다. 그리고 개발 과정에서 주로 생산되는 문제들은 대화와 관심을 통해서 조금이라도 빠르게 인지하는 것이 중요하다고 언급하며, 조금씩 개선하면 어제보다는 더 나은 오늘을 될 것이란 발언과 함께 강연을 마쳤다.