Play Framework: влияние рабочих мест на модель без гражданства - PullRequest
11 голосов
/ 16 октября 2011

Одна из замечательных особенностей платформы Play заключается в том, что она полностью не имеет состояния и ориентирована только на запрос / ответ.Это действительно хорошо, поскольку позволяет мне развертывать мое приложение в облаке и масштабировать количество экземпляров воспроизведения за моим балансировщиком нагрузки, не беспокоясь о репликации состояния (сеанса) ...

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

Скажем, у меня есть задача обслуживания, которая должна выполняться каждый час, и я для нее определяю запланированное задание.Если я затем разверну несколько экземпляров Play за балансировщиком нагрузки, будет ли это задание запускаться одновременно в каждом экземпляре?И если да, то каков будет хороший подход для обработки заданий, которые должны выполняться «исключительно»?

Я думал о создании нового экземпляра воспроизведения на некластеризованном сервере, повторно используя модель JPAсуществующий (кластеризованный) экземпляр (и, следовательно, подключение к той же базе данных).Этот новый экземпляр будет содержать только задания по обслуживанию, и, поскольку он размещен на некластеризованном сервере, нет риска одновременного выполнения задания.В то же время это позволило бы мне сохранить мой существующий кластеризованный экземпляр полностью без сохранения состояния и легко размещать / балансировать нагрузку.Это был бы хороший подход?

Ответы [ 3 ]

5 голосов
/ 17 октября 2011

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

Еще одна вещь, которую вы можете сделать, это использовать Play.id, чтобы определить и определить, какой экземпляр должен выполнять задания. Мы используем "play start -% prod", "play start -% prod1" ... чтобы запустить приложения и следующее в моем методе doJob ():


doJob(){
   if ("prod".equalsIgnoreCase(Play.id)) {
   ...
   }
}
5 голосов
/ 16 октября 2011

Я бы тоже порекомендовал кластеризовать работу. Вы можете установить семафор в базе данных, чтобы убедиться, что выполняется только одно задание. Еще одна идея - взглянуть на Akka-Framework, который будет включен в Play 2.0. Я думаю, что он имеет встроенный механизм для решения этой проблемы, но я не уверен. У меня нет опыта с Аккой.

2 голосов
/ 19 ноября 2012

Быстро изучив исходный код Play Framework (классы Job и JobsPlugin), я думаю, что они не подходят для использования в кластерной среде, когда важно, чтобы Задание запускалось только один раз за некоторое время.интервал (без введения некрасивых хаков).

Я вижу три возможных решения:

  1. Используйте планировщик заданий, который поддерживает кластеризацию.Очевидный выбор - Кварц .Play также использует части кварца (для разбора выражений CRON), но не часть, которая выполняет планирование.

  2. При использовании Play 2, возможно, перейдите для Akka , который предлагает планировщик .

  3. Измените свою работу так, чтобы не имело значения, когда она запускается дважды (возможно для некоторых случаев использования).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...