Хабрахабр

Надёжность World of Tanks Server

Надежность игры — это trade off, потому в разработке игр все нужно делать быстро и быстро изменяться. Сегодняшняя тема — надежность World of Tanks Server — достаточно скользкая. Левон Авакян на РИТ++ рассказал, что в Wargaming делают для обеспечения надежности. Нагрузка на серверы большая, а пользователи склонны что-нибудь поломать просто из интереса.

В этом нет ничего сверхъестественного, а доклад был посвящен моментам специфичным именно для Танков. Обычно, когда говорят про надежность, все время упоминают мониторинги, нагрузочное тестирование и прочее.

О спикере: Левон Авакян работает в компании Wargaming в должности Head of WoT Game Services and Reliability и занимается проблемами надежности танкового сервера.

Сегодня я расскажу о том, как мы это делаем, в том числе, что такое вообще World Of Tanks сервер, из чего он состоит, на чем построен, чтобы вы понимали предмет разговора. Дальше рассмотрим, что может пойти не так внутри самого сервера и вокруг него, потому что игра — это уже больше, чем сервер. А также поговорим немножко о процессах, потому что многие забывают, что хорошо налаженный процесс в производстве — это часть успеха не только с точки зрения экономии ресурсов (многие практики пришли с реального производства), но влияет на качество и надежность решения.

Я это сюда не включил, потому что считаю, что это скучно.
Обычно, когда говорят про надежность, все время упоминают мониторинги, нагрузочные тестирования и прочее. Да, у нас тоже есть система мониторинга, мы занимаемся нагрузочным тестированием со стресс-тестами для того, чтобы повысить надежность системы и знать, где она может отвалиться. Ничего сверхъестественного мы в этом не открыли. Но сегодня я буду рассказывать о том, что более специфично именно для танков.

BigWorld Technology

Это движок бэкенда, а также инструментарий для создания MMO.

Процессы запускаются на кластере, объединенных между собой в сеть, машин. Этот достаточно старый движок BigWorld Server (зародился в конце 90-х — начале 2000-х) представляет собой набор различных процессов, которые поддерживают игру. Взаимодействуя между собой, процессы показывают пользователю какую-то игровую механику.

Для Танков это подходит идеально. Движок называется BigWorld, потому что на нем очень хорошо делать игры, в которых есть большое поле (space), на котором происходят боевые действия (баталии).

С точки зрения надежности в BigWorld были вложены следующие основные фичи:

  • Балансировка нагрузки. Движок выделяет ресурсы, пытаясь достигнуть двух целей:
    1. использовать как можно меньше машин;
    2. при этом не нагружать свои applications настолько, чтобы их нагрузка превышала некоторый предел.
  • Масштабируемость. Добавили машину в кластер, запустили на ней процессы — значит, можно больше обсчитывать боев и принимать игроков.
  • Высокая доступность. Если, допустим, свалилась одна машина или что-то пошло не так с одним из игровых процессов, который обслуживает саму игру, в этом нет ничего страшного — игра не заметит, восстановится в другом месте и будет работать.
  • Сохранение целостности и согласованности данных. Это уже второй уровень отказоустойчивости. Если есть несколько кластеров, как в Танках, и произошла какая-то катастрофа в дата-центре или на магистральном канале, это не значит, что игровые данные, которые человек отыграл, мы утеряем полностью. Мы восстановимся, консистентность будет.

Процессы, которые есть в нашей системе, и их функции

  • CellApp — процесс, отвечающий за обработку игрового пространства или его части.

Как я уже говорил, BigWorld работает с некими пространствами, которые мы делим на клеточки. Каждую конкретную клеточку нашего игрового пространства обсчитывает конкретный application.

  • CellAppMgr — процесс, координирующий работу CellApp, балансировка нагрузки.

CellApp может быть много, соответственно, должен быть процесс, который ими управляет.

  • BaseApp управляет сущностями, изолирует клиентов от работы с CellApp.

Одной из основополагающих вещей в BigWorld является понятие сущности — это, например, аккаунт игрока. Все, что мы делаем на боевом поле, мы делаем с этой сущностью. CellApp’ы рассчитывают физику и игровую механику, например, стрельбу. С сущностями работает BaseApp. Он обслуживает аккаунт, танк и т.д.

  • ServiceApp — специализированный BaseApp, который реализует какой-то сервис.

Это упрощенный вариант BaseApp — процесс, который выполняет разные служебные вещи. Например, кто-то должен уметь читать из RabbitMQ. Это не про игровые сущности, но тоже нужны.

  • BaseAppMgr управляет BaseApp и ServiceApp, потому что их тоже много.
  • LoginApp создает новые подключение от клиентов, а также проксирует пользователей на BaseApp.
  • DBApp реализует интерфейс доступа к хранилищу (базам данных). Мы работаем с Percona, но это может быть и другая БД.
  • DBAppMgr координирует работу DBApp.
  • InterClusterMgr управляет межкластерной коммуникацией.
  • Reviewer — процесс-инспектор, может рестартовать процессы.
  • BWMachineD — демон, который запускается на каждой машине кластера для координации его работы. Он позволяет всем BaseApp-менеджерам общаться между собой.

Так выглядят Танки изнутри, если очень коротко:

  • Клиенты подключаются через интернет, попадают на LoginApp.
  • LoginApp их авторизует с помощью DBApp и выдает адрес от BaseApp.
  • Дальше клиенты играют на них.

Все это разбросано по множеству машин, на каждой из которых есть BWMachineD, который умеет всем этим управлять, оркестрировать и т.д.

Экосистема World of Tanks

Что же вокруг? Казалось бы, есть игровой сервер и игроки — выбрал танк, поехал играть. Но, к сожалению (или к радости), игра развивается, и одной игровой механики «просто пострелять» уже не хватает. Соответственно, игровой сервер стал обрастать различными сервисами, одни из которых вообще невозможно было сделать внутри сервера, а другие мы стали специально выносить наружу для того, чтобы увеличить скорость доставки контента игроку. То есть быстрее написать маленький сервис на Python, который делает какую-то игровую механику, чем делать это внутри сервера на всех BaseAPP’ах, поддерживать кластеры и пр.

Другие мы выносим, потому что Wargaming разрабатывает не одну игру, в конце концов. Некоторые вещи, например, платежные системы изначально были вынесены. Если бы они были внутри BigWorld, то тогда их нельзя было бы удобно использовать в других продуктах. Это трилогия: Танки, Самолеты, Корабли, а есть Blitz и планы на новые игры.

Все шло достаточно быстро и хаотически, из-за чего получился некоторый зоопарк технологий, которые используются в нашей танковой экосистеме.

Основные технологии и протоколы:

Python 2.   1. 5; 7, 3.

Erlang;   2.

Scala;   3.

JavaScript;   4.

Фреймворки:

Django;   5.

Falcon;   6.

asyncio;   7.

Хранилища:

Postgres;   8.

Percona.   9.

Memcached и Redis для кэширования.   10.

Все вместе для игрока это и есть танковый сервер:

  • Единая точка авторизации;
  • Чат;
  • Кланы;
  • Платежная система;
  • Турнирная система;
  • Мета игры (Глобальная карта, Укреп. районы);
  • Танковый Портал, Клановый портал;
  • Управление контентом и т.д.

Но если разобраться, это немного разные вещи, написанные на разных технологиях. Это вызывает некоторые проблемы с надежностью.

Здесь есть игровой сервер, web-сервисы (внутренние и внешние), в том числе совершенно особые сервисы, которые находятся в бэкенд-сети и выполняют служебные функции, и сервисочки к ним, которые фактически реализуют интерфейсы. На схеме представлен наш танковый сервер вместе со своей экосистемой. Например, есть клановый сервис со своим клановым порталом, который позволяет управлять этим кланом, есть портал самой игры и т.д.

Но это приводит к дополнительным усилиям, потому что нужны прокси, которые будут давать доступ, если нам нужно прокинуть это вовне. Такое разделение позволяет нам меньше беспокоиться о безопасности, потому что во внутреннюю сеть ни у кого нет доступа — меньше проблем.

Появилась задача это все как-то включить в клиент. Я уже говорил, что мы приняли решение о том, чтобы часть игровой логики и других вещей вынести из сервера. У нас есть прекрасный Client Gateway, который позволяет танковому клиенту напрямую, минуя сервер, получать доступ к некоторым из API этих Internal Services — к тем же кланам или API наших мета-игр.

У нас открывается теперь такой же браузер. Плюс еще внутрь танкового клиента мы впихнули Chromium Embedded Framework (CEF). Это позволяет работать со всей инфраструктурой, минуя работу с игровым сервером. Игрок не отличает его от игрового окошка.

Так выглядит СНГ-регион. У нас много кластеров — так получилось — дальше расскажу, почему.

Игроки, в зависимости от того, где получше пинг, соединяются с локацией. Все раскидано по дата-центрам. Но вся экосистема так не масштабируется, она находится в основном в Европе и в Москве, что тоже добавляет нам некоторые проблемы с надежностью — лишние latency и пересылки.

Так выглядят экосистема World of Tanks.

Все, что угодно! Что же со всем этим хозяйством может пойти не так? И идет J. Но разберем по кусочкам.

Основные точки отказа внутри кластера

Отказ одной машины или процесса

Простейший вариант, который мы можем спрогнозировать — это отказ одной машины или процесса внутри кластера. У нас есть кластеры от 10 до 100 машин — что-нибудь может вылететь. Как я уже говорил, сам BigWorld предоставляет из коробки механизмы, которые позволяют нам быть более надежными.

На этих BaseApp существуют сущности, которые держат в себе state сущностей. Стандартная схема: есть BaseApp’ы, которые раскинуты по разным машинам. Каждый BaseApp бэкапирует себя Round Robin’ом на других.

На остальных BaseApp’ах остались эти сущности, они будут восстановлены, и игровой процесс для игрока не пострадает. Допустим, у нас произошел фейл и какой-то BaseApp умер, либо вся машина умерла — ничего страшного!

CellAPP’ы делают точно также, единственно, что они хранят свои states тоже на BaseApp’ах, а не на других CellAPP.

Вроде бы это надежный механизм, но…

За все нужно платить

Со временем мы стали наблюдать следующее.

  • Создание резервных копий сущностей начинает отнимать все больше системных ресурсов и сетевого трафика.

По сути процесс бэкапирования начинает сам по себе влиять на стабильность системы, когда внутри кластера большая часть сети занята тем, что передает копии Round Robin’ам.

  • Размер сущностей со временем растет, так как добавляются новые атрибуты и игровые механики.

Например, игрок выполняет какие-то действия (покупает игровое имущество), а эта операция начала тормозить. Но самое неприятное, что размеры этих сущностей растут лавинообразно. То есть системе и так плохо, а мы еще начинаем наращивать размер бэкапа, который нужно сделать. Мы ее еще не выполнили, но сохранили изменения этих атрибутов. Возникает эффект снежного кома.

  • Стабильность системы в целом падает

За счет того, что мы пытаемся спастись от падения одной машины или процесса, мы роняем стабильность всей системы.

Мы решили у каждой сущности выделять то, что действительно нужно бэкапировать. Что мы сделали для того чтобы с этим справиться? Этим самым мы просто уменьшили количество информации, которую действительно железно нужно сохранить. Мы разделили атрибуты на изменяемые и неизменяемые, и копируем не всю сущность, а делаем резервную копию только ее изменяемых атрибутов. Но в целом ситуацию нам это спасло. Сейчас, при добавлении нового атрибута, тот, кто этим занимается, должен более четко смотреть, куда его отнести.

В Кораблях, например, ребята это поддерживают. Если уж быть совсем откровенным, этот механизм заложен в BigWorld, но в Танках в какой-то момент его перестали поддерживать до конца, и не каждая сущность может восстановиться из своего бэкапа. К сожалению, в Танках не всегда так получится, но мы добьемся возвращения всего этого функционала, чтобы он работал так, как ему положено. Там спокойно можно выключать машины — информация просто восстановится на других машинах, и клиент не заметит ничего.

Отказ дата-центра. Мульти-кластер

Если вдруг упала не 1-2 машины, а мы начали терять целый дата-центр, то есть кластер полностью, какие должны быть свойства у системы для того, чтобы в такой ситуации игра не упала?

  • Каждый кластер должен быть независимым, то есть:
    1. должна быть своя база данных;
    2. кластер обрабатывает только свои пространства (боевые арены).

    Таким образом, если какие-то арены попадали, другие еще пока работают.

  • Кластеры должны общаться между собой, чтобы один мог сказать второму: «Я упал!» Когда он поднимется, данные восстановятся из сохраненных копий.
  • Желательно еще, чтобы можно было перевести пользователя с кластера на кластер.

В данный момент схема нашего мульти-кластера выглядит так.

На центральном кластере не запущены CellApp, в остальном он абсолютно такой же, как и все остальные. У нас есть центральный кластер и то, что мы называем перифериями, на которых собственно ведутся бои. То есть выход из строя любого из кластеров не ведет к потере работоспособности всей игры. Он является центральной точкой обработки аккаунтов: они там поднимаются, пересылаются на периферию, и на периферии уже человек играет. Даже выход из строя центрального кластера просто не даст возможность логиниться новым игрокам, но те, кто уже играет на перифериях, могут продолжать игру.

На самом деле таких inter claster manager‘ов можно несколько поднять. То, что у нас все работает через центральный кластер, получилось потому, что вообще сама технология BigWorld предполагает, что есть специальный управляющий процесс inter claster manager.

Когда мы достигли в пике 200 тысяч игроков, то входящий трафик от них просто перестал помещаться в дата-центр по сети. Исторически сложилось, что Танкам нужен мульти-кластер, потому что лавинообразно стал расти онлайн. Нам пришлось буквально на коленке придумывать какое-то решение, чтобы можно было игроков запустить в несколько дата-центров.

Это также стало полезным для игроков, потому что пинг, то есть доступность по сети, сильно влияет на игровой процесс. На самом деле мы только выиграли, потому что у нас теперь есть мульти-кластер. На клиенте нет никаких расчетов. Если задержка больше, чем 50-70 мс, это уже начинает сказываться на качестве самой игры, потому что в Танках абсолютно все просчитывается на сервере. Конечно, там делают некоторые моды, но они не влияют на сам процесс. Поэтому учтите, что там практически ничего нельзя сделать. Можно пытаться предположить, что произойдет, но повлиять на саму game-механику — нет.

Все было замкнуто на нем. За счет такого подхода у нас центральный кластер стал точкой отказа. Тогда там действительно не нужно хранить большие объемы информации — бои себе играются и играются — давайте все замыкать туда. Мы решили — раз уж там стоят эти машины и большая игровая логовая база, пусть наши периферии будут заниматься обслуживанием исключительно боев.

Но мы решили, во-первых, научить периферийные кластеры общаться между собой. Переписывать абсолютно все, для того чтобы уйти от концепции центрального кластера, сейчас уже нет ни времени, ни особенного желания. Дальше мы пропилили в них дырку, чтобы можно было с помощью сторонних сервисов на них воздействовать.

Дальше уже внутренними механизмами сущности перемещались, создавалась сущность арены и т.д. Например, чтобы раньше создать бой, нужно было обязательно сказать центральному кластеру, что нужно создать бой на какой-то из периферий.

Но пока нет желания полностью переходить к схеме, в которой все кластеры практически одноранговые, и все это управляется какими-то процессами, но не кластером. Сейчас есть возможность напрямую обращаться к периферии, минуя центральный кластер. Так мы убираем с него лишнюю работу.

Напоминаю, что кроме игрового кластера со своими BaseApp’ми, CellApp’ми и прочим, у нас есть экосистема.

В худшем случае, допустим, не работает турнирная система, но в рандом можно играть — все равно большинство людей играют в рандом. Мы стараемся делать так, чтобы работоспособность экосистемы никак не влияла на игровой процесс. Да, качество мы понизили, но в целом можно пережить несколько часов без турниров.

Во-первых, есть уже такие веб-сервисы, которые достаточно глубоко вшиты в игру. Не всегда так получается. Например, единая точка авторизации — это сервис, который позволяет авторизоваться на вебе или где-то в одном месте, и фактически быть авторизованным во всей вселенной Wargaming.

Его тоже пришлось привнести внутрь игры только потому, что нам понадобилась трассировка покупок игрока. Второй пример — сервис, который обслуживает игровые покупки и транзакции. Система изначально этого не предполагала, никто на это не закладывался 5 лет назад, но закон суров: нужно делать — делай. Дело в том, что в некоторых регионах мы обязаны выводить информацию в клиент о том, какое игровое имущество было куплено за реальные деньги, а какое за игровые.

Точки отказа в экосистеме World of Tanks

Проблема № 1. Повышенная нагрузка

У нас мульти-кластер, в котором 10 кластеров с огромным количеством машин. Игроки на них играют, а веб — он маленький. Никто не покупает в каждом дата-центре еще пяток машин. Но при этом мы предоставляем все ту же функциональность и все, что нужно, прямо внутри клиента. Это основная проблема.

Интерактивность и реактивность интерфейса — это основной источник повышенной нагрузки на экосистему.

Приведу два примера из кланового сервиса:

  1. Вы хотите пригласить другого игрока в клан. Конечно, хочется, чтобы у приглашенного об этом сразу же появилось уведомление, и он бы смог присоединиться к вам. Для реализации этого нужно сделать так, чтобы клановый сервис как-то мог нотифицировать клиента, либо пусть клиент сам время от времени спрашивает у веб-сервиса: «Не поменялось ли чего? Нет ли у меня новых приглашений?» Это первый вариант, откуда может взяться лишняя нагрузка.
  2. В Танках есть режим укрепрайоны. Предположим, в него играет не один человек, а несколько. У всех игроков открыто окошко с укрепрайонами. Командир построил здание. Желательно, чтобы у всех, у кого открыто это окошко, здание тут же появилось.

Решение в лоб с опросом не очень хорошее. На самом деле оно рабочее, просто мощностей на это нужно выделять столько, что никакого профита для компании эта фича не принесет. А если фича не приносит профит, то и делать ее не надо.

Мой личный совет, как с этим справиться: лучший способ сделать систему надежнее под нагрузкой — вообще уменьшить нагрузку как-нибудь логически.

Не стоит закладываться железом, придумывать новомодные системы, что-то оптимизировать — все равно, чем больше нагрузка, тем больше артефактов будет появляться, от которых вы не сможете уйти. Причем артефакты будут возникать еще на более и более низких уровнях абстракции — сначала с applications, потом с разными веб-сервисами, дальше вы в сеть попадете (cisco и т.д.). На каком-то уровне вы просто не сможете решить проблемы.

Если хорошенько подумать, то их можно просто избежать.

Например, когда приходит приглашение в клан, мы говорим серверу: «Мы таких-то людей пригласили», и дальше сам кластер кластеров находит того, кому нужно послать уведомление, тем более что у них есть соединение. Первое, что мы сделали — это научились нотифицировать клиентов через игровой сервер, используя его инфраструктуру. Это позволяет сделать сервис, который умеет присылать через сервер в клиент нотификацию из экосистемы, что резко уменьшает нагрузку на саму экосистему. То есть мы делаем push из сервиса, а не нас кто-то постоянно «поллит». Мы теперь можем, бросая нотификации клиенту, практически управлять им извне.

Например, в укрепрайонах мы стали использовать Web-sockets. Второе — это Web-sockets (nginx-pushstream). Там есть pushstream, который позволяет нам в Web-sockets соединение посылать изменения состояний укрепрайона конкретного игрока. Как я говорил, в клиенте у нас есть Chromium Embedded Framework — браузер поднимается, когда открывается окошко, Web-sockets подключается к Nginx.

Проблема № 2. Сложный путь данных

Следующая проблема, с которой сталкивается инфраструктура, заключается в том, что экосистема — это микросервисы. Они и сейчас модные, и раньше были модными, их очень много — путь данных получается тернист. А чем длиннее путь данных, тем больше точек отказа, появляются циклические зависимости.

Вариантов много: что-то сложилось исторически, что-то возникает, потому что мы пытаемся сделать решение на вебе не только для одной игры, но для множества игр. Почему так получается? Это усложняет всю работу. Соответственно появляются какие-то абстракции, интерфейсы, прокси.

С точки зрения надежности это выглядит примерно так.

Поэтому граф так ужасен. Я посчитал, что в нашей экосистеме примерно 120 сервисов работают вокруг Танков для обеспечения Game Play. Но обращаю ваше внимание на то, что есть каналы коммуникации между всеми микросервисами и самим сервером. Я не буду здесь затрагивать аспекты построения правильных архитектур, потому что это уже данность, которую я никак не могу изменить. О них и поговорим.

Пути коммуникации

Существует 3 основных канала, которые мы используем:

  1. HTTP API;
  2. RabbitMQ — диспетчер сообщений;
  3. Apache Kafka последний год используется как шина.

Изначально я планировал их сравнить, но это у меня, честно говоря, не получилось, потому что это как сравнивать бульдозер, гоночную машину и трактор. Вроде бы они все машины, цель плюс-минус одинаковая — ездить, но сравнивать их сложно. Поэтому у меня родилась идея на своем опыте Танков рассказать, как эти каналы коммуникаций правильно использовать.

Правильное использование

1. HTTP

Он из коробки, всегда работает, нативен для веб-разработчика, поэтому он у нас всегда используется. Самый простой вариант — это HTTP. Но важно про него помнить следующее:

  • Запросы не должны быть блокирующими (как на клиентской, так и на серверной стороне).

Желательно, чтобы это было асинхронно, если мы говорим про надежную нагруженную систему. Есть мои любимые инциденты, когда у нас, допустим, синхронная Django, и один из 100 или 200 запросов, которые есть внутри API, просто тормозит. Запросы забивают все ядра, очереди начинают копиться, и буквально из-за 30-40 запросов, которые прислали пользователи за минуту, складывается вся система. Это типичный кейс, типичная болячка — асинхронщина в этом смысле помогает.

  • Отсутствие ответа или ошибка должны обрабатываться.

Вторая вещь, про которую часто забывают, когда используют HTTP, — он на самом деле не очень надежный. Таймауты и ошибки нужно корректно обрабатывать. Обычно считается — дернул — всегда получил. По моему мнению, разработчики оптимистичны, а надежность, наоборот, предполагает пессимизм.

  • Необходимо следить за объемом сообщений.

Этот пункт относится к предыдущему. Часто бывает следующее. Есть какой-то сервис, который представляет какой-то API — чаще всего это API, который позволяет выгребать данные из некой базы данных.

Например, есть хороший запрос, который позволяет получить данные по клану. Приведу пример снова из кланов — я про них все время говорю, потому что раньше занимался надежностью кланов. Соответственно, вы в один HTTP запрос начинаете запихивать мегабайты данных. Допустим, разработчик предоставляет возможность спросить про 10 кланов, а какой-то нехороший потребитель спрашивает про 100 кланов или про 500. От этого плохеет nginx’у и вообще всем, просто по таймауту вы не пролазите — опять крах.

В принципе, я ничего против HTTP не имею, просто нужно его аккуратно и в правильных местах использовать.

2. RabbitMQ

Сам по себе RabbitMQ из коробки шел в BigWord как средство коммуникации с кластером.

  • Хорошо использовать для сглаживания нагрузки.

Он отлично у нас работает для сглаживания нагрузки — какой-то пик пришел, лежит в очереди, когда смогли, вычитали.

  • Хороший вариант «шины», если у вас сервис, на который хорошо бы подписаться и получать события.

Опять пример про кланы: мы хотим следить за составами кланов. Когда следит один сервис, он может запрашивать по API: «Дай мне состав клана до события N и после него — я буду это обрабатывать». Потом появляется второй сервис, который хочет знать про конкретный клан, третий, четвертый, пятый — в итоге у вас нагрузка на клановый сервис начинает расти. Причем кэшировать вы особенно не можете, потому что желательно отдавать свежие данные.

Ставите «кролик», пишите туда «эвентики», все желающие подписались — вы убрали нагрузку достаточно дешево и надежно.

  • Нежелательно скапливать большие объемы сообщений.

RabbitMQ всем хорош, но лично мне не нравится тем, что, когда есть проблема с его кластеризацией, если в нем большое количество сообщений, он начинает разваливаться, причем не просто падает и лежит, а пытается приподняться.

Мой совет — не скапливайте в RabbitMQ большие объемы сообщений и надолго.

3. Kafka

Это случилось потому, что в RabbitMQ нельзя хранить что-то долго и писать большие объемы. Третий вариант коммуникации с кластером, да и внутри сервера, к которому мы пришли — это использование Kafka.

  • Продюсер пишет большой объем данных.

Большие объемы у нас появились, когда мы решили писать сервисы вокруг сервера, а не внутри него, и получать боевую статистику. Боев много, статистики тоже, доставать ее из баз данных не очень удобно. Плюс многие сервисы хотят этим заниматься. Логично использовать Kafka. Он, как большая дыра — мы туда просто пишем, а все желающие читают.

  • Данные можно читать не сразу.

Плюс писать можно много, данные там хранятся некоторое время. Если упали и не смогли их сразу прочитать, или данных слишком много, чтобы их пережевать нужно какое-то время — то их можно хранить днями.

Но это вне рамок этой статьи. Про Kafka могу рассказывать долго, мы целый год потратили, чтобы привести в порядок его использование для того, чтобы он стал более-менее надежным источником данных, и на него можно было бы положиться.

Менеджеру на заметку

Как маленькая вишенка на торте — как мы разрабатываем Танки.

Сложности:

  • Танки делает распределенная разработка. Есть основная минская команда и команды в других локациях, которые делают какие-то фичи, модели и т.д.
  • У нас гетерогенная среда — множество команд, языков, технологий, потребителей.
  • Игровая индустрия делает свой вклад — бизнес и игроки требуют все и сразу, нужно все делать быстро. Если вы не можете быстро делать фичи, то очень быстро деградируете, и игроки разбегутся.

Это все давит на разработку. Мы начинаем забивать на надежность, как, например, с бэкапом entity. Но это плохо. Мы вроде бы экономим, но такие вещи начинают накапливаться, и в итоге всем становится только хуже.

DLC

Мы пришли к тому, что придумали DLC (Development Lifecycle) — точнее, не придумали, а просто зафиксировали.

DLC состоит из фаз, и важным аспектом в данном случае является то, что на каждой из них описаны входные и выходные артефакты. Он достаточно большой и сложный, но важно, что он есть. Главное, чтобы она выдавала на выходе то, о чем договаривались все внутри танковой разработки, да и компании в целом. Внутри фазы каждая команда может делать все, что хочет.

Но на более мелких проектах, на которых я пробовал работать по такой системе, это приносило больше пользы, чем негатива. На самом деле мы сейчас находимся на стадии пилота введения DLC, потому что есть и противники этой схемы.

Если вы строите свой DLC, стоит учесть сложности, с которыми мы столкнулись:

  • Фазы нельзя пропускать (даже если очень спешим и очень хочется).

Вы должны формировать набор артефактов, который переходит от одной команды к другой, зафиксировать, и все должны договориться, что работают именно так. Если вы договорились о процессе, как вы будете работать, даже в угоду «очень-очень нужно, мы потом доделаем», фазы нельзя пропускать.

  • С самой первой фазы должны участвовать технические специалисты: Архитектор и SRE.

Идеи вроде бы неплохие, понятно, что это все для того, чтобы сделать игру лучше и порадовать игроков. Важным аспектом является то, что solution-архитектор, technical-owner, reability-инженеры —технические специалисты должны участвовать с самой первой фазы, когда идет пре-продакшен и прототипирование, потому что часто game-дизайнеры и маркетологи фонтанируют идеями. Возврат назад намного дороже, чем если мы делаем сразу. Но иногда какая-то мелочь, если ее не обработает технический специалист, может сильно усложнить систему, или просто не вписываться в то, что уже написано.

  • SRE участвует во всех фазах.

Если никто не спросит это на самом начальном этапе разработки, то часто на это никто и не закладывается. Этот пункт очень перекликается с темой мониторинга — какие бизнес-фичи мы должны мониторить. В самой разработке SRE должен участвовать, потому что разработчики всегда говорят: «У меня на ноутбуке работает, а что у вас там за мощности, какая у вас виртуализация, как вы это раскатываете — никому не интересно!» Если сразу же проследить и сделать, потом будет проще. Это один из кейсов, почему SRE должен участвовать на уровне пре-продакшена.

Если на стадии тестирования мы совместно с QA работаем, помогаем организовывать нагрузочное тестирование, какие-то дополнительные вещи, например, тестирование нефункциональных требований — тоже всем будет проще.

Подытожим

BigWorld Technology из «коробки» предоставляет отличные механизмы для обеспечения надежности игры. Мы их до конца не используем, но обещаем. Но это все равно не спасает нас от проблем. Нет «серебряной пули», чтобы сделать систему надежнее.

Вторая часть — «разделить» (вынести, распараллелить) — дает хороший эффект производительности труда. Принцип «разделяй и властвуй» отлично работает до тех пор, пока вы контролируете все компоненты, то есть фактически властвуете. Соответственно, где-то приходится уступать. Мы можем делать быстрее и лучше, но с точки зрения надежности контроль сильно усложняется.

Никто не торопился расходиться, и Левон еще 40 минут отвечал на вопросы и по теме надежности, и просто про Танки. Бонус: Этот доклад был завершающим в первый день фестиваля РИТ++. Можно перескочить сразу в конец доклада и послушать, может быть обсуждались интересующие вас аспекты.

Мы решили организовать отдельную профессиональную конференцию по DevOps 1 и 2 октября в Москве, в Инфопространстве. Конференция RootConf переживает ребрендинг — теперь это DevOpsConf Russia. Смотрите, какие заявки на доклады получил Программный комитет — есть из чего выбирать!
Планируем обсудить все тематики, которые актуальны для специалистов по информационным системам.

Теги
Показать больше

Похожие статьи

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Кнопка «Наверх»
Закрыть