Main > Magento > Magento 2: Планировщик задач

Magento 2: Планировщик задач

01.06.2019 1 comment » Views: 1,510

Magento 2

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

выведет что-то типа

установить эти команды в cron можно выполнив

удалить, выполнив

Итак, крон запускается каждую минуту. После запуска выполняется метод execute из класса CronCommand, который наследуется от класса Symfony\Component\Console\Command\Command

В нем парсятся и проверяются входные данные и если все Ок, создается экземпляр класса \Magento\Framework\App\Cron у которого вызывается метод launch

Далее происходит создание события "default" и его выполнение. Любой модуль может подписаться на это событие. Как вы можете заметить, событие вызывается в зоне crontab  (areaCode = crontab), поэтому подписку надо делать в файле <ModuleName>/etc/crontab/events.xml, например так:

это событие запускается каждый раз когда вызывается php bin/magento cron:run, т.е. при настройках по-умолчанию - каждую минуту.

Одним из подписчиков на это событие является класс: Magento\Cron\Observer\ProcessCronQueueObserver, который и отвечает за запуск задач по расписанию.

Задачи конфигурируются с помощью фалов <ModuleName>/etc/crontab.xml расположенных в модулях. Пример:

Обработка задач происходит в методе Magento\Cron\Observer\ProcessCronQueueObserver::execute()

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

В magento 2.3.0 этот метод немного поменялся, добавили сортировку групп, чтобы группы имеющие флаг Use Separate Process выполнялись первыми. Выглядит это так

Формат у таблицы cron_schedule такой:

  • schedule_id - номер записи
  • job_code - id задачи (например: indexer_update_all_views)
  • status - статус выполнения. Может быть:
    • pending - задача запланирована на выполнение, дата запуска указана в колонке scheduled_at
    • running - означает, что задача была запущена на выполнение и работает
    • success - означает, что что задача была выполнена
    • missed - означает, что прошлый запуск этой задачи не завершился, до момента запуска текущей задачи. Другими словами в момент запуска этой задачи, она проверила эту таблицу и нашла запись с таким же job_code и статусом running.  Если после этого задача так и не смогла запуститься в период указанный в настройках, например 5 минут, то она помечается, как missed. Период, задается в админке:
    • error - указывает, что выполнение прошло с ошибкой. Пояснения к ошибке находятся в колонке messages.
  • messages - поясняющее сообщение, используется в случае ошибок
  • created_at - время, когда задача добавлена в таблицу
  • scheduled_at - время, когда запланировано выполнение
  • executed_at - время, когда задача была запущена на выполнение
  • finished_at - время, когда задача закончила работу

Для каждой из задач в файле /etc/crontab.xml задается группа

Из коробки, у нас есть 4е группы:

  • default - основная группа
  • indexer - индексаторы
  • consumers - группа очереди сообщений модуль Magento_MessageQueue
  • ddg_automation - группа dotmailer модуля (dotdigital Engagement Cloud)

Например, в группу index входят задачи с такими id:

Если вам необходимо создать свою группу, например для того чтобы запускать интеграции со сторонними сервисами, то делается это с помощью файла <ModuleName>/etc/cron_groups.xml

Далее используете id новой группы в файле <ModuleName>/etc/crontab.xml

Наиболее просто найти список всех задач и их расписание, можно при помощи утилиты n98-magerun2: https://github.com/netz98/n98-magerun2

Сделать это можно с помощью команды: php n98-magerun2.phar sys:cron:list

Для каждой из групп в админке задаются настройки. Найти настройки можно тут

Magento 2: Настройки крон

Magento 2: Настройки крон

Разберемся с настройками для групп

  • Generate Schedules Every - добавлять задачи в таблицу cron_schedule каждые N минут
  • Schedule Ahead for - время которое будет добавлено к времени scheduled_at
  • Missed if Not Run Within - время после истечения которого задача будет отмечена как missed, в случае если в списке есть задача в статусе running. Т.е. если задача не была выполнена в течении N минут, после scheduled_at, она будет отмечена как missed. Задача не может быть выполнена, в случае, если уже есть другая задача с тем же job_code в статусе running.
  • History Cleanup Every - История задач будет очищаться, каждые N минут
  • Success History Lifetime - История задач со статусом success будет очищаться каждые N минут
  • Failure History Lifetime - История задач со статусами missed и error будет очищаться каждые N минут
  • Use Separate Process - Использовать отдельный процесс для запуска задач из этой группы.

На Use Separate Process остановимся подробнее. Эта опция используется в классе Magento\Cron\Observer\ProcessCronQueueObserver, в методе execute

и выглядит так

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

Если изучить этот метод чуть дальше, станет понятно для чего нужен запуск в отдельном процессе, немного ниже видно как запускаются задачи:

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

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

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

После того, как задача будет выполнена, её статус в таблице cron_schedule обновится с running на success. Очень часто бывает, что в случае криво написанных интеграций или других задач, выполнение прерывается с фатальной ошибкой, например, при превышении памяти отведенной на запуск php процесса. В таком случае, задача останется висеть в статусе running, в этом случае все последующие добавленные задачи не будут выполнены и будут переводиться в статус missed. В этом случае, необходимо вручную изменить статус задачи на error, выполнив такой SQL код:

Полезные ссылки

Author: | Rating: 4/5 | Tags: ,

1 comment.

Write a comment

Leave a Reply

Your email address will not be published. Required fields are marked *

Allowed HTML-tags: <a>, <code>, <i>, <em>, <strong>, <b>, <u>, <strike>


Links to this post:
  1. Pingback from Magento 2: Как работает индексация 02.06.2019