Pull to refresh

Comments 12

Фотки схем это конечно круто… Ещё и рукописный текст. Ничего не разобрать же?
Можно было б для статьи и нарисовать такие простенькие схемы.
Почерк более чем разборчивый, процентов на 90
Я не совсем понимаю, что там такого на серваке может долго выполняться, чтоб понадобился ConcurrentMap. У нас серверный игровой инстанс не на Java, но сотни пользователей держит без проблем на 1 потоке (Unity3d headless build). Все тяжёлые запросы вроде запросов к БД асинхронны.
Не совсем вас понял.

У меня есть контроллеры, принимающие реквесты от пользователей. Их обслуживает thread-pool (около 20 потоков). Соответственно между ними возникает конкуренция за шареные ресурсы.
Так же есть еще поток GameLoop. Он тоже дополнительно обращается к шареным ресурсам. Следовательно, надо еще и его учитывать с позиций потокобезопасности.

Ну и в статье я описал как решаю следующие проблемы:
— Реквесты с игровыми действиями обладают максимальным приоритетом перед другими типами запросов (например, логин, заявка на игру).
Чтобы не было такого, что пришло 100 запросов на аутентификацию и «забили» thread-pool (обслуживающий пользовательские запросы). При этом поступающие игровые действия вставали бы в очередь, и все игры разом “притормозили” бы на несколько секунд.
— Неблокирующая многопоточность.
Чтобы не было проблем при вертикальном масштабировании и увеличении количества обслуживающих потоков.

Неблокирующие коллекции позволяют записывать данные без «глюков» при одновременных запросах разными потоками. А также решают ряд других проблем, например, безопасное чтение третьим конкурирующим потоком.
Мне понравилась эта статья в тему потокобезопасных коллекций: www.ibm.com/developerworks/ru/library/j-jtp07233/index.html

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

У меня встречный вопрос: у вас, как я понял, GameLoop также запущен в одном потоке. Но контроллеры, вероятно, обслуживаются пулом потоков. Каким образом происходит синхронизация между контроллерами и игровым циклом?
Реквесты с игровыми действиями обладают максимальным приоритетом перед другими типами запросов (например, логин, заявка на игру).
Чтобы не было такого, что пришло 100 запросов на аутентификацию и «забили» thread-pool (обслуживающий пользовательские запросы). При этом поступающие игровые действия вставали бы в очередь, и все игры разом “притормозили” бы на несколько секунд.

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

У нас подход другой. Мы прикидываем, сколько игроков тянет инстанс (а он однопоточный), а потом просто по числу ядер запускает инстансы.
Клиенты у вас коннектятся по (веб)сокетам? Если да, то как происходит горизонтальное масштабирование игровых серверов? Или же, как планировалось у меня, — сервера никак не связаны друг с другом (игроки с разных серверов не могут играть друг с другом и не видят друг друга)?

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

А микросервисную тоже не стал рассматривать по той же причине. Плюс к тому же непонятно как это хостить на бесплатном аккаунте. Плюс время разработки увеличивается. А у меня не было ни бюджета, ни ресурсов, ни времени.
К Api/Auth серверам через http. Эти сервисы за балансером стоят, так что я их могу сколько угодно насоздавать.

Api выдаёт нужный инстанс по Round-robin'у, клиент к нему потом по udp коннектится. Инстансов можно тоже сколько угодно создавать. Единственное проблемное место пока только это матч мейкер. Он в одном экземпляре.

Находят друг друга на сервере все сервисы через consul.io
Резюмируя

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


Резюмируя: я такими формулировками в институте писал в работах для галочки. Куча воды, а потом ХОБА и прекрасный результат. Преподы делали вид что поняли, я делал вид что написал что-то дельное, никто не терял лица друг перед другом и мы расходились по сторонам. Примерно также и тут.
Спасибо за комментарий.

Исправил этот абзац. Я его действительно написал не особо думая. Также подправил первую часть статьи.

Сейчас всё понятно написано или остались ещё непонятные абзацы?
Sign up to leave a comment.

Articles