게임은 게임 본연의 기능 이 외에도 유저가 게임을 직접 하기까지 마켓 출시를 위해 신경 써야 할 부분들이 있습니다. 유저를 식별할 수 있는 로그인 과정이 있어야 하며 출시하는 국가마다 법령에 따른 약관이나 나이에 따른 안내, 개발자의 공지를 보여줄 수 있는 보드, 이벤트를 안내할 수 있는 배너와 노티피케이션, 그리고 안정적인 구매 시스템인 빌링과 이에 따른 백엔드 서비스와 이를 관리할 수 있는 백오피스까지 고려해야 할 부분이 많죠.
모바일 게임 플랫폼인 ‘Hive’에서 SDK 란, 게임에 필요한 이런 기능을 미리 구축하여 제공하는 도구 모음입니다.
SDK는 사용자가 사용하기 전 이 기능들을 준비해야 하며, 그렇기 때문에 초기 부분에 많은 동작이 들어갈 수밖에 없는 구조가 됩니다. 약관 동의 같은 필수 통과 로직을 비롯해 SDK에 기능이 많아질수록 점점 규모가 커지고 있고 이는 초기화 속도가 느려지는 결과가 되어 SDK를 사용하는 개발자와 게임을 플레이하는 유저 모두에게 좋지 못한 경험이 되었습니다.
SDK의 초기화 속도 검토 결과 일반적인 상황에서 수 초 이상의 초기화 필요 시간을 확인하여 게임 진입 속도 개선이 필요하다고 판단, 단축 방향에 대해 검토를 시작하였습니다.
목차
초기화 시간을 차지하는 요인
1차 개선 : 파일 읽기/쓰기와 연산
2차 개선 : 병렬 통신과 병합
2차 개선 : 통신 재시도와 분산서버
개선 결과
마치며
초기화 시간을 차지하는 요인
SDK의 초기화 시간은 디바이스 사양이나 네트워크 상태 등 여러 요인이 있지만 다음의 4가지를 중점으로 측정하였습니다.
파일 읽기/쓰기 : 기기 스토리지에 읽고 쓰는 시간
연산 : 응답 결과를 처리하는 로직 시간
UI : 유저에게 노출되는 UI 시간
네트워크 통신 : 서버와 네트워크 통신에 소요되는 시간
<표 1. 초기화 단계별 평균 소요시간 측정 결과>
<표 2. iOS 초기화 로직 중 평균 파일 읽기/쓰기 측정 결과>
실제 측정에는 여러 환경에서 수차례 이루어졌으며 Android / iOS 모두 디바이스의 사양 및 네트워크 상태에 따른 초기화 로직 수행 시간에 영향을 받았습니다. 네트워크 통신이 포함된 로직 수행 시 타 구간보다 많은 시간이 소요되는 것을 확인할 수 있었고, 10단계의 서버 통신 및 관련 데이터 처리 로직은 직렬적으로 처리되고 있었습니다. 또한 iOS의 경우 Property 저장을 위한 파일 읽기/쓰기 과정에서 상당한 시간이 소요된 부분을 확인할 수 있었습니다. 실제 게임의 경우 SDK 초기화 시점에 게임의 다른 통신 및 게임 로직이 수행되어 샘플보다 더 많은 시간이 소요될 수 있을 것으로 보았습니다.
이에 따라 SDK 초기화 과정을 경량화하기 위한 방안과 목표를 수립하였습니다.
방안 수립
목표 : 저사양 단말의 3G 환경에서 평균 1.5~2초 수행
iOS Property 저장을 위한 파일 읽기/쓰기 수행 횟수 최소화
통신 API 중 통합 가능한 API에 대한 검토
통신 중 병렬 처리 가능한 것에 대하여 병렬 처리 진행
초기화 수행 진척도를 안내하여 초기화 지연에 대한 유저 경험 개선
백그라운드 이미지 다운로드 과정이 게임 통신에 영향을 미칠 수 있으므로 개선
서버 내 서비스 로직을 담당하는 Gateway 서버를 구축하여 일관적인 서비스 수행 속도 보장
Keep-alive 설정 같은 경우, 방안으로 검토되었지만 커넥션 속도가 0.000 단위로 의미가 없다고 판단되었습니다. 단일 서버 구성이고 파이프라인 렌더링 처리가 될 때만 유지되는데 요즘 수많은 언어나 스크립트에서 제공하는 HttpReuqest 라이브러리들은 Keep-alive 렌더링 처리가 안되어 1:1 연결 처리가 되었습니다.
1차 개선 : 파일 읽기/쓰기, 연산
초기화 동작에는 여러 이해관계가 얽혀 있습니다. 단순 특정 통신전에 선행되어야 하는 통신 순서부터 게임 플레이를 위해 노출되어야 하는 약관, 유저 동향을 파악하기 위해 필요한 통계 전송은 약관 전에 이루어지면 안되는 점, 기기의 기능 사용을 위해 필요한 일부 기기 권한 중 약관 전에 필요한 권한도 있으며 게임별 필터링 되어야 하는 나이나 국가 제한 등은 약관 동의 전에 되어야 유저 경험이 좋은 부분도 있습니다. 약관의 노출 시점 변경 같은 경우 법무팀의 검토가 필요하며 로직의 위치 변경은 통계의 순서 변경을 의미해 사전 협의도 필요하게 되죠.
그래서 근본적인 개선 방향을 진행하는 장기적인 플랜과 단기적으로 개선할 수 있는 파일 읽기/쓰기 와 연산 부분을 병행하여 전반적인 SDK 경량화를 수행하기로 하였습니다.
AutoSave 기능 비활성화 AutoSave 기능은 설정값의 변경시마다 파일로 자동 저장해 주어 데이터 유실을 방지하는 기능이었으나 여러 설정값을 한꺼번에 변경 시 설정값 개수만큼 파일 쓰기가 차례로 발생하는 문제가 있었습니다. 이 부분을 명시적으로 저장 포인트를 찾아 저장하도록 변경하였습니다.
기존 값과 동일한 경우 저장하지 않도록 변경 불필요한 파일 쓰기를 방지하기 위해 기존 값과 비교하여 파일 쓰도록 하였습니다.
개선 후 파일 쓰기 작업 횟수는 최초 실행 시 44회에서 12회 감소하였고 이후 사용자는 5회까지 감소하였습니다.
<표 3. 파일 읽기/쓰기 개선 전/후 평균 소요 시간>
처음 측정 시 Property 저장이 수차례 발생하여 지연이 발생하는 것으로 분석된 로직들뿐 아니라, 불필요한 파일 쓰기 제거로 인하여 다른 구간에서도 눈에 띄는 소요 시간 변화가 보인 것을 확인할 수 있었습니다. 특히 파일 읽기/쓰기 성능에 큰 영향을 미치는 저사양 기기에는 개선이 발생한 모습을 확인할 수 있었습니다.
2차 개선 : 병렬 통신과 병합
초기화 시간을 차지하는 4가지 요인 중 네트워크 부분은 가장 큰 요인이며 통신 횟수에 따른 차이가 크게 나타나게 됩니다. 시간이 지나면서 SDK는 기능이 누적되면서 서버 통신 및 관련 데이터 처리 로직이 순차적으로 진행되었습니다. 이번 개선은 이 부분을 병합하여 최적화하는 방법입니다. 특히, 데이터를 가져오는 통신들은 하나의 통신으로 묶어 가져오면 통신 횟수를 획기적으로 줄일 수 있습니다.
필요 순서가 같은 통신들은 병렬로 처리해 한 번의 통신만큼 소요 시간이 걸리도록 변경하였습니다. iOS는 기본적으로 4개의 네트워크 스레드까지 가능하며, Android는 iO Coroutine을 사용하여 멀티 스레드로 구현하였습니다.
UI가 있는 부분 같은 경우 UI 노출 동안 백그라운드에서 통신을 동시에 진행하여 체감되는 소요시간을 단축하였습니다.
그림 1. Hive SDK Setup flow – Current
그림 2. Hive SDK Setup flow – Parallel processing
결과적으로
8개의 통신 부분 중 2개의 통신과 신규 기능이 확장형 API 하나로 병합되어 물리적인 통신 횟수가 감소하였고 4개-2개씩 2단계의 병렬 통신으로 변경되어 체감되는 소요시간이 2개로 단축되었습니다. 다른 하나의 통신은 UI 노출 도중 백그라운드에서 동작하도록 변경되었습니다.
2차 개선 : 통신 재시도와 분산 서버
통신 최적화에 좀 더 들어가면 다음의 4가지 요인으로 세분할 수 있습니다.
1. 클라이언트의 요청 2. 서버 처리 시간 3. 실패에 따른 재시도 로직 4. 응답 결과에 따른 연산
클라이언트의 요청은 통신 횟수와 직결되며 위의 병렬 통신과 병합 최적화로 줄일 수 있었습니다. 응답 결과에 따른 연산은 1차 개선에서 이루어졌으며, 네트워크 환경 요인으로 인한 응답 딜레이를 제외하면 서버의 처리시간은 문제없이 동작하고 있었습니다. 서버 처리 시간은 다음과 같습니다.
<표 4. 서버 API 별 평균 처리 시간>
SDK는 통신이 원활하지 않을 경우에 대비하여 재시도 로직을 가지고 있으며 Hive 서버 또한 분산 환경을 제공하고 있습니다. 재시도 로직은 여러 가지 방법이 있지만 네트워크 환경이 좋지 않은 해외 지역의 순간 단절 현상 대응에 초점이 맞춰져 있으며 상용 서버 통신에 실패를 기다린 후 분산 서버로 한 번 더 요청하도록 되어 있습니다.
자세한 기존 로직은 다음과 같습니다.
1. 상용 서버에 네트워크 통신 요청 (Thread A) 2. 5초 이내 응답을 받지 못했을 경우 같은 통신을 한 번 더 요청 (Thread B) 3. 둘 중 먼저 오는 성공 응답을 사용 4. Thread B까지 실패하면 분산 서버로 다시 A, B 반복
동남아 지역 환경처럼 순간 단절 현상이 심한 네트워크 환경에서 문제가 되었던 부분들이 많이 해소되었던 방법이나 이 로직의 문제점은 매번 상용 서버로 먼저 요청을 하게 되는데, 상용 서버가 문제가 생겼을 경우 매번 Timeout 이 될 때까지 과도하게 기다리게 되는 것입니다. 극단적인 상황으로 가정하면 여러 통신이 몰려있는 초기화 부분은 이론상 약 150초를 기다리게 됩니다.
이 부분을 분산 서버로 통신 시도 시, 이후 통신은 앱 재시작 전까지 상용 서버와 분산 서버를 같이 시도하여 대기 시간이 단축되도록 하였습니다. 자세한 내용은 다음과 같습니다.
한 번이라도 분산 서버 통신을 진행했을 때, 다음 통신부터는 Thread B에서 분산 서버로 요청
분산 서버로 교체된 Thread B까지 실패할 경우 4번째의 재시도를 하지 않음
분산 서버 진행 여부 값은 메모리에만 기록하여 앱 재시작 시 초기화 되도록 함
설정에서 명시적으로 재시도하지 않도록 할 경우 분산 서버 진행 여부 값에 따라 1회 통신으로 동작
Thread A 응답이 먼저 오더라도 실패일 경우 Thread B까지 대기
또한 Hive 서버는 분산 환경이 인증에 집중되어 있었으나 시작부터 로그인 진행까지 필요한 서비스에 대해 확대 적용되어 초기화 자체가 실패하는 경우를 줄여 더 안정적인 진행이 가능해졌습니다.
개선 결과
네트워크 통신 개선 확인을 위하여 3G 환경에서 테스트를 진행하였습니다. 단말의 편차가 있긴 하지만, SDK 전체적으로 30% 정도의 초기화 속도가 개선되었습니다.
Unity 샘플의 경우 초기화 시간이 평균 28% 단축되었습니다.
Android : 평균 24.2초에서 평균 17.3초로 단축
iOS : 평균 26.4초에서 평균 19.2초로 단축
<표 5. Unity 샘플의 테스트 결과>
Cocos 샘플의 경우 초기화 시간이 평균 37.5% 단축되었습니다.
<표 6. Cocos 샘플의 테스트 결과>
마치며
게임팀이 게임 이외의 부분에 신경 쓰지 않고 게임 개발에 전념할 수 있도록 하는 것이 초기 목표였던 Hive는 작은 모듈 라이브러리에서 시작하였습니다. 이제는 게임 플랫폼으로서 Hive는 SDK를 비롯해 다양한 백엔드 서비스와 함께 강력한 기능을 제공하고 있습니다. 글로벌 서비스를 염두에 두고 축적된 경험을 바탕으로 더 많은 부분이 개선되어 전 세계 유저들에게 원활하게 서비스되기를 기대합니다.
단순하게 하나의 공간을 뜻하는 용어에서 소프트웨어와 서비스 등 추상적 관점으로 그 개념이 확장된 모빌리티 플랫폼은 모바일 기반 앱 플랫폼이 시장을 선도하고 있고 공급자와 수요자를 직접 연결하는 온라인 공간이 되었습니다. 빠르게 진화하는 플랫폼 생태계에서 Hive는 서로의 가치를 연결하고 플랫폼의 브랜드가 곧 나의 브랜드가 될 수 있도록 최선을 다하겠습니다.