За кулисами закрытого бета-тестирования Skyforge
Сегодня я хочу рассказать о первой части закрытого бета-тестирования (ЗБТ) Skyforge. Это уже не первое ЗБТ, но зато оно стало самым массовым. Большинство игроков составляют не сотрудники компании и их друзья, а поклонники игры, выбранные случайно из числа зарегистрировавшихся для участия в тесте, а так же купившие или выигравшие наборы раннего доступа. С вечера пятницы, 6 февраля, и до конца выходных будет организован специальный бета-уикенд, во время которого доступ на ЗБТ будет открыт всем пользователям, имеющим аккаунт в почте Mail.Ru. Этот пост носит повествовательный характер и передаёт мою личную точку зрения на происходившие до и во время ЗБТ события.
Самые первые тесты Skyforge проводились исключительно внутри команды разработчиков, всё делали своими силами. С течением времени игра становилась стабильнее, соответственно, и расширялся круг лиц, допущенных к тестированию. Сперва мы показали игру коллегам по Allods Team. Затем — игровому департаменту Mail.Ru Group. Потом — всему коллективу компании. Начиная с этого этапа, все тесты уже проводились отдельной командой — командой оперирования. Внешние тесты шли на стенде, который готовился к проведению ЗБТ и, впоследствии, ОБТ.Для того чтобы закрытое бета-тестирование было продуктивным, мы тщательно готовили нашу инфраструктуру. Проводили нагрузочные тесты на серверах ЗБТ, настраивали сбор различных метрик, приём крашей, анализ логов и многое другое. И вот, когда всё было готово, мы открыли заслонку и впустили первых реальных пользователей.
Как только начали заходить игроки, мы сразу стали искать трансляцию на Twitch, чтобы увидеть реакцию пользователей, понять, насколько хорошо справляется сервер, да и просто из любопытства. Большая часть студии смотрела трансляцию ничего не подозревающего геймера, а какие-то советы на правах обычного пользователя ему давал даже директор по качеству. Мы начали получать первые отчёты с боевых серверов — проблемы с авторизацией на веб-портале, краши клиента, ошибки подключения отдельных игроков. Но, в целом, старт прошел успешно: аккаунт-сервер справился, а сервера игровой механики не тормозили. Что, впрочем, неудивительно, потому что мощности железа, по нашим данным, должно было хватить и на куда большее число пользователей. Нам повезло, что сервер Skyforge написан на Java. Этот язык нативно поддерживает механизм HotSwap, горячую замену кода без остановки приложения. Так как серверов у нас достаточно много, то мы даже написали специальную утилиту, которая пробегает по ним и патчит. Этот инструмент пригодился нам уже во время старта ЗБТ. Когда мы поняли, что у нас есть баг при загрузке пользовательских аватарок для чатика, то просто закомментировали данную функциональность.
Для пользователей потеря аватарки осталась почти незамеченной, зато некоторым серверам жить стало значительно легче. В следующем же патче эту функциональность выключили сразу.
В принципе, техника точечного патчевания настолько же крута, насколько и страшна, и без полной уверенности в успехе ею лучше не пользоваться.
С точки зрения тестирования серверу, к счастью, повезло гораздо больше, чем клиенту. Мы знаем спецификацию железа, на котором сервер будет работать, знаем точное окружение, сами задаём настройки. Клиенту в этом плане гораздо сложнее. В ходе разработки у нас есть 10–20–30 различных конфигураций ПК, на котором запускается клиент. Это компьютеры самих разработчиков. После выхода в свет количество конфигураций идет на тысячи. И у каждой из них могут быть свои особенности: экзотические драйверы, видеокарты и прочие компоненты. Поэтому первая волна новых игроков стала жертвой массовых крашей и проблем с производительностью. Но благодаря нашей системе сбора статистики по железу и производительности удалось оперативно внести необходимые улучшения. Сейчас вся работа команды также направлена на улучшение стабильности и увеличение FPS.
Именно по таким тепловым картам мы оцениваем FPS игроков на открытых зонах.
Выход тестирования за пределы круга друзей и членов семьи познакомил команду сервера с некоторыми странностями реального мира. Так, например, несколько пользователей страдали из-за особенностей своей сетевой инфраструктуры — новому соединению доставался новый внешний IP. Таким образом, когда игрок телепортировался с одной карты на другую, у него менялся IP. И мы его честно отключали от сервера, т.к. считали эту ситуацию невалидной. Но уже после нескольких поставленных тикетов пришлось отключить проверку IP в рамках одной игровой сессии как излишне параноидальную. Другие проверки валидности пользователя мы оставили.Если вы читали статью про архитектуру нашего сервера, то знаете, что он состоит из множества распределенных серверов, каждый из которых живет на своём хосте и выполняет определённую роль: сервер авторизации, сервер игровой механики, сервер баз данных и так далее. При разработке мы старались делать так, чтобы падение отдельно взятого сервера не было фатальным и большинство пользователей могли продолжать играть. Но реальность оказалась жестче, чем мы думали.
Иногда сервера падают целыми стойками. Первый раз нам «повезло», когда полностью обесточилась стойка с порталом и несколькими серверами игровой механики. Мы считали, что игроки поведут себя так: те, кому не повезло оказаться на обесточенных серверах, спокойно перезаходят в игру и продолжают играть дальше, правда, потеряв прогресс прохождения персональных карт, которые остались на умершей механике. К сожалению, так как выключение было нештатным и хосты механик пропали полностью, сервер-координатор не получил сообщение о разрыве соединения. Лично для меня это было не самое ожидаемое поведение TCP keep-alive. Оказалось, что keep-alive начинает отправлять пакеты по неактивным TCP-соединениям по истечении некоторого (по умолчанию — очень длительного) таймаута. Это сделано для того, чтобы не захламлять канал, когда всё хорошо. В принципе, можно было выставить значение таймаута для каждого подключения индивидуально, но для этого бы потребовались грязные хаки. Поэтому мы договорились сделать своё решение: простой механизм пинг-понг опроса серверов. Его плюс в том, что админы на удаленных территориях не смогут его случайно отключить, в отличие от TCP keep-alive, а мы можем отключать серверы, которые ушли, например, в серию Full GC.
После того как мы обсудили эту идею, договорились реализовать её до ОБТ. Всё-таки не каждый день хосты обесточиваются.
Когда мы в режиме реального времени увидели указанный выше график, то подумали, что резкое падение количества активных пользователей — это признак окончания рабочего дня. Но оказалось, что упал хост с механикой номер 13. Два падения за неделю — это все ещё совпадение. Но уже значительная часть команды сервера изучает логи, где и что можно улучшить в консерватории. И вот тут, в последнюю пятницу года, за несколько часов до корпоратива, хост с механикой номер 13 падает опять. А впереди Новый Год и 12 дней праздников, которые хочется провести вдали от работы. Решили-таки отключить несчастливую механику. И с тех пор подобных инцидентов больше не было. Но чтобы Новый Год прошёл спокойнее и падение отдельных механик не приводило к срочным профилактическим работам, мы в тот же корпоративный вечер приготовили первую версию фикса. Тестировали мы её по-честному: запускали на локальных ПК распределённую версию сервера и выдёргивали провод питания из механической части. Фикс был признан рабочим и ушёл на боевые во время последних профилактических работ 2014 года. Новогодние праздники в итоге прошли спокойно.
107 — именно такой код у ошибки превышения тайм-аута при подключении к серверу. Эта ошибка, к сожалению, получила широкую известность среди игроков, участвующих в ЗБТ. И с ней связано сразу несколько довольно интересных фактов.Баг, или даже баги, приводящие к ошибке 107, были внесены в сетевой движок довольно давно — за несколько месяцев до старта ЗБТ. И первыми об таймаут споткнулись боты. Но тогда был то ли дефицит времени, то ли я не смог разобраться с причинами, но в ботах в итоге просто отключили всяческие таймауты. В результате баг, к несчастью, доехал до боевых.
Дальше мы стали свидетелями того, как несколько активных пользователей могут создать иллюзию важности той или иной проблемы. Ошибка 107, как показало исследование, могла возникнуть только у пользователей, имеющих пинг в районе ~3 мс, причём вместе с обработкой в коде, как на сервере, так и на клиенте. К сожалению, фикс только ухудшил ситуацию: исчезновение ошибки было отмечено у очень небольшого процента пользователей, зато она появилась у гораздо большего числа игроков.
Это были пользователи, которые играют в Skyforge через 3G/4G-модемы и/или слабые ПК. Мы никак не могли повторить этот новый баг локально. К счастью, у нас есть боты. Мы включили в них таймауты и починили код их обработки, сразу же получив просто вал ошибок 107. Дальше починить баг было уже делом техники. После выдачи фикса на боевую популярность ошибки 107 сошла почти на нет. Сейчас есть всего 1 незакрытая жалоба.
На самом деле было сразу несколько причин ошибок 107:
слишком хорошее сетевое подключение и быстрый клиент (пинг < 3 мс); нестабильный и/или плохой пинг (3G- и 4G-модемы); медленные клиенты или слишком большая общая загруженность системы (копирование файлов); счастливые обладатели CD/DVD-ROM (при старте клиент собирает статистику о железе). Урок ошибки 107 в очередной раз показал, как важно исследовать не до конца понятное поведение в системе. А также — как важно иметь на руках объективную статистику по распространению тех или иных ошибок у игроков. Такая статистика, кстати, должна появиться уже к старту ОБТ.Сухая статистика:
X — Регистраций всего0.96*X — Z1. Остров Данкит0.84*X — Z2. Раскопки Исолы0.58*X — Z3. Ланберский лес0.37*X — Z4. Остров Наори0.11*X — Z5. Миленские пещеры
К сожалению, абсолютные значения опубликовать нельзя. Хотя на мой скромный взгляд, они более чем достойные.
Закрытое бета-тестирование — это один из важнейших этапов перед запуском игры для широкой аудитории. На мой взгляд, наша команда справилась с прошедшим этапом ЗБТ вполне достойно. Хочу поблагодарить всех пользователей, принявших и принимающих участие в ЗБТ, ваши репорты помогают делать игру лучше. А также приглашаю всех на стресс-уикэнд. Надеюсь, что вместе у нас получится заставить сервер трещать по швам :)