cron-like дизайн планировщика повторяющихся задач - PullRequest
8 голосов
/ 20 октября 2010

Скажем, вы хотите запланировать повторяющиеся задачи, такие как:

  • Отправлять электронную почту каждую среду в 10:00
  • Создать сводку в первый день каждого месяца

И вы хотите сделать это для разумного числа пользователей в веб-приложении - т.е. 100 000 пользователей каждый пользователь может решить, что они хотят запланировать, когда.

И вы хотите, чтобы запланированные элементы выполнялись, даже если они были пропущены изначально - например. По какой-то причине электронное письмо не было отправлено в среду в 10:00, оно должно быть отправлено в следующий интервал проверки, скажем, в среду в 11:00.

Как бы ты это спроектировал?

Если вы используете cron для запуска приложения планирования каждые x минут, каков хороший способ реализовать часть, которая решает, что должно выполняться в каждый момент времени?

Кроноподобные реализации, которые я видел, сравнивают текущее время со временем срабатывания для всех указанных элементов, но я бы также хотел иметь дело с пропущенными элементами.

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

Ответы [ 3 ]

6 голосов
/ 20 октября 2010

В основном 2 дизайна.

Выполняется регулярно, сравнивает текущее время со спецификацией планирования (т. Е. «Это выполняется сейчас?») И выполняет те из них, которые соответствуют требованиям.

Другой метод берет текущую спецификацию планирования и находит СЛЕДУЮЩИЙ раз, когда элемент должен срабатывать. Затем он сравнивает текущее время со всеми теми элементами, у которых «следующий раз» меньше «текущего времени», и запускает их. Затем, когда элемент завершен, он переносится на новый «следующий раз».

Первая техника не может обрабатывать «пропущенные» предметы, вторая техника может обрабатывать только те предметы, которые были запланированы ранее.

В частности, учтите, что у вас есть расписание, которое запускается раз в час, в начале часа.

Так, скажем, 1:00, 14:00, 15:00, 16:00. * 10101 *

В 13:30 задача запуска не работает и не выполняет никаких процессов. Это не начинается снова до 3:20 вечера.

Используя первую технику, планировщик запустил задачу на 1 час, но не запустил задачи на 2 часа и 3 часа дня, так как в те времена он не выполнялся. Следующее задание будет выполнено в 4 часа дня, ну, в 4 часа дня.

Используя вторую технику, планировщик запустит задачу на 13:00 и назначит следующую задачу на 14:00. Поскольку система не работала, задача 2 часа дня не выполнялась, как и задача 3 часа дня. Но когда система перезапустилась в 3:20, она увидела, что «пропустила» задание в 2 часа дня, и запустила его в 3:20, а затем снова запланировала его на 4 часа дня.

У каждой техники есть свои взлеты и падения. С первой техникой вы пропускаете работу. Со вторым методом вы все еще можете пропустить задания, но они могут «наверстать упущенное» (до определенного момента), но могут также выполнить задание «в неподходящее время» (возможно, оно должно выполняться в самый разгар рабочего дня для причина).

Преимущество второго метода заключается в том, что если вы перенесете график в КОНЦЕ выполнения задания, вам не придется беспокоиться о каскадной задаче.

Учтите, что у вас есть работа, которая выполняется каждую минуту. С первой техникой работа увольняется каждую минуту. Однако, как правило, если задание не ЗАВЕРШЕНО в течение одной минуты, потенциально может быть запущено 2 задания (одно запаздывает, другое запускается). Это может быть проблемой, если задание не рассчитано на одновременное выполнение более одного раза. И это может усугубить ситуацию (если возникнет реальная проблема, через 10 минут у вас будет 10 рабочих мест, все сражаются друг с другом).

Со вторым методом, если вы запланируете в конце задания, то если задание будет выполнено чуть более минуты, то вы «пропустите» минуту и ​​запустите следующую минуту, а не продолжите работу Таким образом, вы можете назначить задание на каждую минуту, фактически выполняемую в 13:01, 13:03, 13:05 и т. д.

В зависимости от вашей работы, любой из них может быть «хорошим» или «плохим». Здесь нет правильного ответа.

Наконец, реализация первого метода на самом деле довольно тривиальна по сравнению с внедрением второго. Код для определения того, соответствует ли строка cron (скажем) заданному времени, прост по сравнению с определением, в какое время строка cron будет действительной в СЛЕДУЮЩЕМ. Я знаю, и у меня есть пара сотен строк кода, чтобы доказать это. Это не красиво.

4 голосов
/ 21 октября 2010

Если вы хотите пропустить проектирование и начать использовать, взгляните на сельдерей http://celeryproject.org/. Планировщик называется сельдереем.

Edit: Также актуально: Как отправлять 100 000 писем в неделю?

2 голосов
/ 20 октября 2010

Использование резервного Java-процесса с Кварцевый планировщик является вероятным потенциальным решением.Я считаю, что кварц должен достаточно хорошо масштабироваться до этого уровня.См. Этот связанный вопрос SO: «Как масштабировать Кварцевый Планировщик» ...

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

Вычеркнуто, так как спрашивающий специально искал обсуждение проекта ... Если вы создали свой первоначальный поиск StackOverflow ранеечтобы задать вопрос в терминах «планировщиков заданий для Python», вы бы включили это: «Планировщик предприятия для python ...» .Я настоятельно рекомендую искать существующую реализацию, а не пытаться разрабатывать NIH для чего-то подобного, несмотря на большие наблюдения о том, как вы могли бы сделать это в другом ответе.Учитывая ваши заявленные цели по масштабируемости, вы отмахиваетесь от довольно сложной задачи, и вам следует исключить все другие опции, прежде чем идти по пути с нуля по столь же сильно развитой теме, как эта.Одним из возможных путей рассмотрения будет адаптация к хорошо известному Quartz через Jython и определение того, можно ли обрабатывать ваши сценарии использования в этом контексте с минимальным погружением в мир Java (предположительно, не ваш первый выбор).

...