200명이 동시에 들어오면 : 웹게임 혼자 만들기(15)
문을 열기 전에 꼭 확인하고 싶은 게 있었다. 사람이 한꺼번에 몰리면 이 게임이 버티나. 그래서 200명이 동시에 들어온 상황을 흉내 내 보기로 했다.
가짜 이용자 200명
실제 사람 대신 가짜 이용자로 시험했다. 한 명은 가입하고 캐릭터를 만든 다음 쉬지 않고 사냥을 돈다. 캐릭터 보고, 사냥터 목록 보고, 사냥 시작. 다섯 바퀴마다 가방이랑 홈도 열고, 체력이 떨어지면 여관에 간다. 요청 사이엔 1초쯤 쉰다. 버튼을 꽤 빨리 누르는 사람인 셈이다.
인원은 25명, 50명, 100명, 200명으로 늘려 가며 단계마다 가입이 다 끝나고 잠깐 기다린 뒤 60초씩 쟀다.
목표도 미리 정해 뒀다. 200명일 때 홈이나 캐릭터 같은 주요 화면이 0.1초 안에 뜰 것. 사냥 결과는 0.2초 안. 오류는 0. 시간은 평균이 아니라 제일 느린 5%를 뺀 나머지가 다 들어오는 값으로 쟀다. 평균은 몇 명이 오래 기다려도 티가 잘 안 나니까.
11초
첫 결과를 보고 철렁했다. 200명일 때 주요 화면을 불러오는 서버 응답이 11.0초. 사냥은 14.8초였다. 0.1초가 목표였는데.
25명일 때부터 이미 0.66초였다. 인원은 8배로 늘었는데 시간은 16배 넘게 늘었다. 서버 프로그램 세 개를 같이 띄웠는데 합쳐서 1초에 요청 20개쯤에서 꽉 막혔다. 오류는 하나도 없었다. 다들 기다리기만 했을 뿐. 근데 화면이 11초 동안 안 뜨면 그건 오류랑 다를 게 없다.
일마다 문을 새로 열고 있었다
원인은 데이터베이스 연결이었다. 게임 서버는 일을 하나 할 때마다 데이터베이스에 새로 연결하고, 끝나면 끊었다. 이 컴퓨터에서 연결 하나 여는 데 33ms쯤 걸렸다. 이미 열린 연결로 간단한 질문 하나 하는 건 0.08ms. 연결을 여는 게 일 자체보다 수백 배 비쌌던 거다.
캐릭터 화면은 한 번 열 때 이런 일을 대여섯 번 한다. 연결 여는 데만 200ms쯤 쓰는 셈이다. 사람이 몰리면 연결을 여는 쪽에서 줄을 서는 것 같았는데, 이건 추정이다. 잰 건 연결 하나에 33ms라는 데까지다.
연결을 돌려 쓰게 했다
고친 방법은 단순했다. 쓴 연결을 끊지 않고 열어 둔 채 다음 일에 다시 쓰는 거다. 흔히 커넥션 풀이라고 부른다. 서버 프로그램 하나마다 쉬는 연결을 10개까지 쥐고 있게 했다. 돌려받을 때는 하다 만 일을 깨끗이 되돌리고, 상대가 끊어 버린 연결이나 너무 오래된 연결은 버린다.
같은 조건으로 다시 쟀다.

200명일 때 주요 화면 59ms, 사냥 147ms. 오류 0. 25명일 때 0.66초였던 게 18ms가 됐다. 서버 프로그램을 네 개로 늘리면 주요 화면 42.6ms, 사냥 100.5ms까지 내려갔다.
반대로 두 개로 줄이면 200명에서 다시 막혔다. 0.73초쯤. 네 개로 300명을 넣어 봤더니 그것도 목표를 넘겼다. 그래서 200명 기준으로는 세 개 이상, 여유 있게는 네 개라고 적어 뒀다.
더블클릭 하나
부하 말고, 같은 일을 동시에 여러 번 보내는 시험도 같이 돌렸다. 거기서 결함이 하나 나왔다.
사냥 시작을 두 번 빨리 누르거나 탭 두 개에서 같은 요청이 동시에 들어가면, 그중 일부가 다른 사냥이 진행 중이라는 거절을 받았다. 실제로는 자기 요청이 처리되고 있는 중이었는데. 사냥이 두 번 정산되진 않았지만 화면만 보면 뭔가 꼬인 것처럼 보인다.
순서 문제였다. 같은 요청이 이미 들어왔는지 먼저 보고, 그다음 캐릭터 차례를 기다린다. 기다리는 사이에 먼저 온 쪽이 접수를 끝내 버리면 뒤에 온 쪽은 그걸 모른다. 그래서 기다린 뒤에 한 번 더 확인하게 고쳤다. 같은 요청이면 그 사냥을 그대로 이어받게. 수정을 되돌리면 실패하는 시험도 두 개 넣었다.
상점 구매, 길드 기부, 거래소, 장비 장착, 강화는 한꺼번에 몰아쳐 봐도 골드가 음수가 되거나 두 번 지급되는 일이 없었다. 측정하는 동안 정산된 사냥만 3만 5천 건쯤이었다.
고쳐 놓고 꺼 둔 채였다
근데 이 장치는 기본값이 꺼짐이었다. 다른 시험들에 영향을 줄까 봐, 켜는 건 따로 정하기로 하고 끈 채로 넣어 뒀다.
며칠 뒤 연속 사냥이 왜 느린지 살펴보다가 같은 걸 다시 만났다. 연속 사냥 50번에 연결을 256번 새로 열고 있었다. 28.7초. 연결 돌려 쓰기를 켜고 재니 1.46초였다. 그래서 이걸 켜고 서버를 다시 띄우는 걸 정할 일 목록에 올렸다.
이 숫자의 한계
이 측정은 전부 내 컴퓨터 한 대에서 했다. 가짜 이용자를 만드는 프로그램이랑 서버랑 데이터베이스가 같은 컴퓨터에서 힘을 나눠 썼고, 인터넷을 거치는 시간도 없다. 사냥 흐름만 돌렸고 거래소나 채팅이 섞인 부하는 재지 않았다. 실제 서버에선 다시 재야 한다.
그래도 11초를 사람들이 들어오기 전에 본 건 다행이었다.
다음엔 전쟁 시험을 접던 날 얘기를 하려고 한다.