Я пытаюсь найти лучшее решение для периодической задачи, работающей параллельно. Требования:
- Java (Spring без спящего режима).
- Задачи управляются внешним приложением и хранятся в БД MySQL (поля:
id
, frequency
(в секундах), <<code>other attributes/settings about task scenario>). - Что-то вроде crontab, только с полем frequency
(секунд) вместо минут / часов / дней / месяцев / дней недель.
Я думаю о:
TaskImporter
поток опроса задач из БД (через TasksDAO.findToProcess()
) и отправка их в очередь.
java.util.concurrent.ThreadPoolExecutor
параллельное выполнение задач (из очереди).
Самая сложная часть этой архитектуры TasksDAO.findToProcess()
:
- Как узнать, какие задачи пора запускать прямо сейчас?
- Я думаю о
next_run
Поле задачи, которое будет заполнено (UPDATE tasks SET next_run = TIMESTAMPADD(SECOND, NOW(), frequency) WHERE id = ?
сразу после выбора (SELECT * FROM tasks WHERE next_run IS NULL OR next_run <= NOW() FOR UPDATE
). Проблема: приходится запускать много ОБНОВЛЕНИЙ для множества задач SELECT (ОБНОВЛЕНИЕ для каждая задача или ОБНОВЛЕНИЕ) + проблемы параллелизма (см. ниже).
- Возможность запуска нескольких параллельных приложений обработки (в облаке), используя / опрашивая одну и ту же БД.
- Все параллельные приложения обработки должны запускать конкретную задачу только один раз. Необходимо заблокировать все SELECT из всех других приложений, пока приложение А не завершит обновление (
next_run
) всех выбранных задач. Проблема: блокировка производственного стола (front-end app) замедлит процесс. Настольное зеркало?
Я люблю простые и чистые решения и считаю, что есть лучший способ реализовать это приложение обработки. Вы видите что-нибудь? :)
Заранее спасибо.
<ч />
РЕДАКТИРОВАТЬ: Использование Quartz в качестве планировщика / исполнителя не вариант из-за задержки синхронизации. Приложение переднего плана не в Java и поэтому не может взаимодействовать с Quartz, кроме решения, ориентированного на Webservice, которое тоже не подходит, поскольку приложение переднего плана имеет больше данных, связанных с ранее упомянутыми Задачами, и требует прямого доступа ко всем данные в БД (чтение + запись).