Подтвердить что ты не робот

Java, quartz и несколько задач, запускаемых в определенные моменты времени, сохраненные в базе данных

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

Каждый пользователь может установить другую дату. Система будет иметь 10k + с самого начала, и пользователь может создать более одного триггера.

Итак, если у меня есть 10k пользователей, каждый пользователь создает в среднем 3 триггера = > 30k триггеров с 30k различными датами.

Все даты сохраняются в базе данных.

Я новичок в кварце, можно ли это сделать более оптимизированным способом?

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

Есть ли у вас лучшие идеи? Кто-то использовал кварц для большого количества триггеров.

4b9b3361

Ответ 1

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

Это проблематичный подход:

  • Проблемы с синхронизацией. Я предполагаю, что пользователи могут редактировать, удалять и добавлять новые задачи в базу данных. Вам придется периодически просить базу данных обновлять состояние заданий кварца, удалять некоторые задания, редактировать другие задания и т.д. Это может быть не тривиально. Состояние программы - это длинный живой кеш, который нужно часто синхронизировать.

  • Проблемы с производительностью и масштабируемостью: даже если предлагаемое решение может быть одобрено для 30K-заданий, может быть не совсем нормально для задач 70k или 700k. В вашем подходе это нелегко масштабировать - для добавления новой машины потребуется дополнительный уровень синхронизации - какая машина должна фактически выполнять какое задание (поскольку все они имеют все задачи).

Что я предлагаю:

  • Добавьте "этап" в таблицу "Задачи" (новая, поставленная в очередь, работающая, закончившаяся, сбой)
  • Разделите решение на несколько компонентов. (Изначально они могут работать на одной машине, но ее легко масштабировать).

Компоненты:

  • Поиск заданий: Выполняется периодически (один раз в несколько секунд). Сканирует базу данных для задач, которые являются "новыми", и скоро. Отправляет задачи, найденные в очередь сообщений, и помещает задачу как "поставленную в очередь" в db. Маркировка как "поставленная в очередь" должна выполняться тщательно, так как может быть несколько "искателей задач". (В качестве дополнения он может найти задачи, которые были отмечены как "queued" или "running" больше, чем N минут назад и не "закончены" или "отменены" - возможно, их нужно повторно запустить)

  • Очередь сообщений: соединитель между Taks Finder и Task Executor.

  • Task Executor: прослушивает очередь сообщений и обрабатывает полученные задачи. Помечает задачи как "запущенные" изначально и "завершенные" или "неудачные" позже.

При таком подходе вы можете:

  • несколько исполнителей задач на нескольких машинах
  • несколько планировщиков заданий на нескольких машинах
  • даже если один из планировщиков заданий или исполнителей будет терпеть неудачу, это не будет Single Point of Failure. Некоторые из задач будут отложены, но они будут подхвачены и запущены впоследствии.

Это может не учитывать все сценарии, но будет хорошей отправной точкой.

Ответ 2

Я не понимаю, зачем вам вообще нужен кварц. Насколько я помню, кварц лучше всего использовать для планирования внутренних процессов, а не для пользовательских задач, полученных из db.

Просто обработайте триггер по мере его создания, сохраните строку в таблице tasks с помощью start_date на основе триггера, и каждая секунда выбирает все незавершенные задачи с помощью start_date < SYSDATE. Если задание повторяется, вычислите следующее время выполнения и соответственно вставьте новую строку/обновление предыдущей задачи.

Ответ 3

Как Sam указали, что есть несколько хороших тем, рассматривающих ту же проблему:

В такой системе, как упомянуто, не должно быть проблем с обработкой этого количества триггеров. Но, согласно моему опыту, это лучший способ создать нечто вроде "JobChecker". Если вы разрешаете своим пользователям создавать собственные триггеры, это может в какой-то степени привести к поломке кварца. Например, если пользователь 5000 создает событие в одно и то же время, Quartz будет иметь трудное время для правильной обработки. (Это маловероятно, что ситуация будет происходить часто, но это возможно, поскольку ваша спецификация не исключает ее.) Кварц испытывает трудности только тогда, когда одновременно запускается много триггеров.

Моя рекомендация по этой проблеме состоит в том, чтобы создать одно задание, которое выполняется в каждый час/минуту и ​​т.д., и которое должно обрабатывать каждый пользовательский набор событий. Этот способ близок к заданию cron в bash. При такой обработке ваша система будет довольно стабильной, даже если количество "триггеров" резко возрастет. В принципе, ваша линия мысли правильна, если вы преуспеете в масштабировании.