글 목록으로

혼자 만든 웹 MMORPG에 사람이 10배 몰리자 벌어진 일

평소 20~30명이던 웹 MMORPG에 239명이 몰린 뒤, 패킷과 스킬을 최적화하고 서버와 사냥터를 손본 이야기.


여러 플레이어가 함께 모닥 온라인 레이드 보스를 공략하는 모습

안녕하세요. 혼자 웹 MMORPG MODAK Online을 만들고 있습니다.

예전에 긱뉴스에 월 $6 VPS 한 대로 MMORPG 동접 1,000명에 도전해봤습니다라는 부하테스트 글을 올렸습니다.

당시 블로그 글 마지막에는 이렇게 썼습니다.

서버 업그레이드를 진지하게 고민할 만큼 많은 유저분들이 놀러와 주시면 좋겠습니다.

어느 날 커뮤니티에 올린 홍보글이 인기를 끌면서, 평소 20~30명이 접속하던 게임에 사람이 몰리기 시작했습니다. 접속자가 계속 늘더니 피크 239명을 찍었습니다.

플레이어들이 모인 사냥터와 현재 235명이 접속 중이라는 시스템 메시지
접속자가 늘던 당시. 채팅창에 235명이 접속 중이라는 안내가 보입니다.

바라던 일이긴 했는데, 막상 사람이 들어오니 서버도 느려지고 사냥할 몬스터도 모자라졌습니다. 그동안 고친 것들을 정리해봤습니다.

1. 봇 300명과 실제 유저 240명은 달랐습니다

이전 테스트에서는 300명까지 괜찮았는데, 이번에는 240명 안팎에서 문제가 생겼습니다.

채팅창에는 렉이 심하다는 말이 계속 올라왔습니다. 렉 때문에 죽었다는 분도 있었고, 여러 지역에서 서버가 터질 것 같다는 반응이 나왔습니다.

아 렉걸려서 뒤짐

서버렉도 2000년대 재현해 놓은거야?

가위바위보 해서 진 사람 나가라

서버비를 후원하겠다는 분도, 유료 아이템을 살 테니 서버를 늘려달라는 분도 있었습니다. 일단 렉부터 잡아야 했습니다.

지난 테스트와 비교해보니 봇이 하는 일부터 실제 유저와 달랐습니다. 당시 봇은 일정 주기로 타깃을 잡고 스킬을 쓰고 전리품을 얻는 정도였습니다. 그 뒤로 게임에 추가된 기능도 있고, 유저들이 성장하면서 사용하는 스킬도 달라졌습니다.

렉이 생기는 동안 스왑 입출력도 급증했습니다. 추적해보니 네트워크 송수신용 메모리를 할당하는 과정에서 메모리 회수가 반복되고 있었습니다. 관련 커널 설정을 조정하고, 서버가 보내는 데이터 자체도 줄이기로 했습니다.

타격과 스킬 이벤트를 묶어 보내고, 필요 없는 필드를 빼고, WebSocket 압축을 적용했습니다. 공통 메시지는 한 번 직렬화한 데이터를 여러 접속자에게 공유하도록 했습니다.

100명이 전투 이벤트를 받는 상황을 로컬에서 재현해 비교했습니다. CPU 사용량은 단건 전송 방식을 100으로 놓았습니다.

전송 방식 WebSocket 전송량 CPU 사용량 (단건 전송 = 100)
이전 단건 전송 형식 재현 29.80MB/s 100
이벤트 묶음 적용 28.23MB/s 22.5
불필요한 필드 제거 + 묶음 + 압축 2.69MB/s 54.7

묶어서 보내니 CPU 사용량이 줄었고, 압축까지 넣으니 전송량이 묶음 방식보다 약 90.5% 줄었습니다. 압축에 CPU를 더 쓰더라도 전송량을 줄이는 쪽을 택했습니다.

여러 사람에게 효과를 주는 스킬도 손봤습니다. 고레벨에 배우는 왕 직업의 광역 버프는 지역의 플레이어를 순회하면서 범위 안 아군에게 효과를 적용합니다. 지원 스킬을 쓰는 사람도, 효과를 받는 사람도 늘어나니 기본 공격 위주였던 봇 테스트보다 할 일이 많았습니다.

전투 깃발 아래에서는 아군의 공격속도가 20%, 이동속도가 10% 올라갑니다. 여러 깃발의 범위가 겹치면 같은 사람의 버프를 반복해서 확인하고 갱신했습니다. 깃발 효과를 틱마다 모아서 처리하고, 이미 같은 버프를 받고 있으면 능력치를 다시 계산하지 않도록 바꿨습니다.

채팅 번역은 배치로 바꿨습니다. 첫 부하테스트 이후 한국어·영어·일본어 채팅 번역을 붙였는데, 사람이 늘면서 대화량도 급증했습니다. 문장마다 번역을 요청하니 LLM 호출도 함께 늘었습니다. 채팅을 하지 않는 봇으로는 겪지 못했던 일입니다.

원문은 바로 보여주고, 번역은 5초 간격으로 최대 10문장씩 모아서 요청하도록 바꿨습니다.

2. 증설했는데도 남은 렉은 호스트를 옮긴 뒤 해결됐습니다

코드를 고치는 동안 유저분들께 공지하고 vCPU도 두 배로 늘렸습니다.

증설 전후에 확인한 CPU 사용률은 이랬습니다.

구분 전체 동접 CPU 사용률
증설 전 227명 약 80~85%
증설·긴급 코드 배포 후 208명 약 37~46%

CPU에 여유는 생겼는데 간헐적으로 게임 전체가 밀리는 현상은 남았습니다. 50ms 주기로 돌아가는 게임 틱이 길게는 1초 넘게 걸렸습니다.

이때 CPU steal을 확인했습니다. VM이 CPU를 쓰려는데 실제 실행 시간을 받지 못하고 기다리는 시간입니다. 테스트 결과에서는 이 값이 30~66%까지 올라갔고, 여러 지역이 함께 느려졌습니다.

그날 밤 업체와 협의해 물리 호스트를 변경한 뒤에야, 원인을 알 수 없던 지연이 비로소 사라졌습니다.

3. 몬스터보다 플레이어가 많아졌습니다

접속자가 늘기 전, 플레이어보다 몬스터가 많았던 사냥터의 3초 플레이 영상
사람이 몰리기 전에는 몬스터가 넉넉했던 사냥터.

사냥터에는 원래 사람이 늘수록 몬스터 스폰 시간을 줄이는 처리가 있었습니다. 다만 대략 열 명이면 가장 빠른 스폰 구간에 도달했습니다. 그 이상 사람이 늘어나는 상황까지는 준비하지 못했습니다.

사람들이 한 필드에 몰리니 몬스터가 나오자마자 사라졌습니다. 급하게 부족한 사냥터의 스포너를 두 배로 늘리고 배치도 분산했습니다. 사람들이 한곳에서 몬스터를 기다리는 대신 나뉘어 사냥할 수 있게 했습니다.

필드 레이드 보스도 너무 빨리 잡혔습니다. 패턴을 3~4번 겪으며 공략하도록 만들었는데, 사람이 몰리니 패턴을 한 번 보고 나면 죽어 있었습니다.

체력을 232만에서 400만으로 약 72% 늘렸습니다. 여럿이 때리더라도 준비한 패턴을 겪을 시간은 있어야 했습니다.

함께 보스를 잡고 받는 경험치도 문제였습니다. 정해진 경험치를 참여자끼리 나누다 보니 사람이 많아질수록 한 명이 받는 양은 줄었습니다. 같이 보스를 잡았는데 경험치가 거의 오르지 않는 상황이 됐습니다.

경험치는 보상 조건을 충족한 사람마다 정해진 양을 받도록 바꾸고, 기본 지급량도 인당 300만으로 올렸습니다.

서버가 버티면 끝일 줄 알았는데, 들어온 사람들이 사냥하고 보스를 잡는 것까지 다시 맞춰야 했습니다.

브라우저에서 가볍게 접속했지만, 누군가와 같이 보스를 잡고 채팅하다 보니 오래 머물게 되는 게임을 만들고 싶습니다. 예전 MMORPG에서 느꼈던 재미와, 같이 놀던 사람들이 기억에 남는 그런 게임이요. 놀러와 주신 분들이 계속 돌아오고 싶은 곳이 되도록 잘 만들어보겠습니다.