Как вы масштабируете сервер приложений, на котором есть задачи daemon?

#synchronization #jetty #scalability #daemon

#синхронизация #jetty #масштабируемость #демон

Вопрос:

У меня есть веб-приложение, которое прямо сейчас работает на одном сервере. Я хотел бы переключиться на кластер серверов приложений (jetty), чтобы справиться с возросшей нагрузкой и отработкой отказа. Однако в приложении есть пара потоков демона, которые запускаются раз в 10 минут для обработки поступивших данных. Эти данные должны обрабатываться только один раз (они обмениваются данными с внешними серверами, и плохие вещи случаются, если это делается дважды).

Каковы наилучшие методы для этого масштабирования?

Некоторые из имеющихся у меня вариантов следующие:

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

  2. Разработайте некоторую систему, в которой разные серверы приложений знают друг о друге и имеют некоторый способ выбора узла для его запуска, например, все выбирают случайное число, и тот узел, который является самым высоким, получает его для запуска. Делайте это каждые 10 минут. Это обеспечивает автоматический переход на другой ресурс (если другие узлы не могут связаться с одним узлом из-за его неработоспособности, он просто игнорируется), но это также означает, что каждый сервер приложений должен знать о каждом другом сервере приложений, и я чувствую, что изобретаю колесо здесь.

Как обычно решается эта ситуация?

Ответ №1:

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

Помимо планирования ваших задач в Quartz, вам нужно будет создать базу данных (или использовать существующую) со схемой Quartz. Время работы всех серверов в кластере должно быть синхронизировано (это сделает ntpd).

Использование Quartz обеспечит отказоустойчивость, балансировку нагрузки и гарантию того, что каждая задача будет выполнена только один раз.

Ответ №2:

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

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