Допустим, есть браузерная игра в которой можно отправить войско, чтобы оно напало на соседа. Войско придет к соседу через час, без моего участия, состоится бой, результат которого будет зависеть от конфигурации войска соседа. При этом, сосед может поменять эту конфигурацию хоть в последнюю секунду.
Т.е. я генерирую событие, которое должно быть обработано в определенное время и результат обработки будет зависеть от актуальных на момент выполнения данных.
Как лучше обрабатывать такие события на сервере?
На ум приходит очевидное — добавлять событие в очередь с параметром «время», фоновый скрипт постоянно проверяет очередь и если есть события, которым пора выполняться, обрабатывает их все по очереди.
Беспокоит меня в таком подходе то, что при большом количестве участников, событий тоже может быть много, в том числе и назначенных на одно время. Их последовательная обработка может занять время и в час Ч, результата еще не будет (т.е игра отобразит что-то там, но не результаты, которых ждут игроки).
Возможно, есть какое-то более логичное решение для отложенных событий? или не стоит переживать по поводу скорости, а делать так, чтобы обработка занимала очень мало времени?
Вопрос как-то странно задан, не понял что вам все-таки нужно… Чтобы все события гарантированно отрабатывали за заданное время? Или чтобы внутреннее состояние системы не нарушилось?
Я бы такого рода задачу решал с использованием менеджера очередей a-la RabbitMQ. Они поддерживают отложенное выполнение задач. Ну а данные о состоянии системы можно получать в момент старта задачи.
Проблема большого кол-ва юзеров решается классическим способом — увеличением кол-ва воркеров… Получать задачи от RabbitMQ могут несколько серверов-воркеров, так что параллелить можно в очень широких пределах.
Для вашего примера: записываете в очередь отложенное событие «напади на соседа». В час Ч эта задача запускается на каком-то из воркеров, берет из БД текущую конфигурацию войск противника и считает результат боя. После обсчета сохраняет в БД или информирует юзера или запускает другую задачу в очередь…
только RabbitMQ — это брокер очередей
а в данном случае необходимо выбрать из очереди событие на конкретной момент времени,
что-то типа очереди с приоритетами
такой возможности в кролике нет В час Ч эта задача запускается на каком-то из воркеров,
как определить этот час Ч?
брать инфу из одной очереди и пихать в другую (на обнове БД) с приоритетами — это бред!!!
Вопрос задан тем, кто имеет опыт разработки серверов онлайн-игр. О том, какие подходы к данной задаче использовали и на каком остановились. К сожалению, мне пока советую либо костыли (нарисуй анимашку и пусть себе тупит), либо то, о чем я не спрашивал (как реализовать очередь итд. я и сам знаю, ну или спрошу отдельно. Я спрашивал о том, какие есть решения кроме очереди или о том, как так обрабатывать очередь, чтобы получать результат незамедлительно), либо вообще бред (типа, купи еще железа). Видимо, разработчики онлайн-игр в данных раздел не заглядывают(
Я работаю в конторе, которая делает а основном онлайн-игры. Но я над смежной задачей работаю, но использую наработки из движка игры. Знаю, что игроделы у нас используют Celery + RabbitMQ. Celery умеет делать отложенные задачи. Если надо — могу поподробнее расспросить в понедельник…
Сергей: а вы можете подсказать, как сделать чтобы внутреннее состояние системы не нарушилось? У меня похожая задача. Мне нужно записать данные в бд и через определенное время выполнить с ними некие действия. Как можно гарантировать, что при записи данных в бд создастся и сообщение в rabbitmq? Чтобы избежать ситуации, когда данные в бд записались, а сообщение в rabbitmq не создалось. То есть мне нужна атомарность, либо всё (запись данных и сообщение в rabbitmq) либо ничего. Это можно как-то сделать? В качестве бд используется mysql.
Написано
Войдите на сайт
Чтобы задать вопрос и получить на него квалифицированный ответ.