19 декабря 2015

Drupal 7: работа с кроном и hook_cron

Евгений Тристамов
Разработчик

Cron (крон) — это планировщик заданий на сервере. Он позволяет настроить выполнение определённых задач с заданной периодичностью.

По крону выполняются задания, которые необходимо запускать регулярно: очистка кэша, проверка обновлений и так далее. Но его можно использовать и для разовых, но объёмных задач. Например, для отправки рассылки на 100 тысяч писем. Отправить их за один раз нельзя, так как почтовые системы могут заблокировать вас за спам, поэтому письма можно рассылать пачками, например, по 1000 писем за один запуск крона.

Системный крон vs крон Друпала 

У Друпала есть «собственный крон» — это php-файл, который запускается (по умолчанию) раз в три часа. Каким образом Друпал понимает, что его надо запустить и как он это делает? Друпал хранит в базе данных время последнего запуска своего крона, и, если посетитель зайдёт на сайт по истечении указанного времени, Друпал вызовет hook_cron во всех включённых модулях.

Системный Cron — это демон операционной системы, который постоянно работает и выполняет различные задачи с указанной периодичностью.

Если настроить системный крон так, чтобы он вызывал cron.php (файл Друпала или «крон Друпала»), то посетители не будут видеть задержек из-за срабатывания hook_cron.

Если вы настроили запуск раз в час, то по истечении часа, при открытии любой страницы сайта будет запущен крон. Крон вызовет функции hook_cron во всех включённых модулях.

Системный крон

Чтобы настроить системный крон — откройте файл /etc/crontab (Debian/Ubuntu) и добавьте в него следующую строчку:

0 */3 * * * root wget -O- http://<MYSITE_NAME>/cron.php?cron_key=<SECRET_CODE> >> /dev/null

Такая запись будет опрашивать «крон Друпала» раз в 3 часа. Ссылку на запуск крона именно на вашем сайте, вы найдёте на странице admin/reports/status.

Чтобы изменения вступили в силу, выполним в консоле на сервере:

service cron restart

Крон Друпала

Старайтесь писать hook_cron не тяжелыми, чтобы крон успел отработаться за 30 секунд.

Разные задачи могут требовать разных интервалов выполнения: каждые три часа, раз в день, раз в неделю. Вы можете это настроить с помощью модуля Ultimate Cron. Он позволит каждому заданию задать свою периодичность запуска.

Рассмотрим этот модуль. Скачаем и включим его через Drush:

drush dl ultimate_cron && drush en -y ultimate_cron

После этого, по адресу admin/config/system/cron вы сможете увидеть подробную информацию о всех задачах крона:

В колонке Operations можно настроить периодичность запуска задач, точнее, способ задания периодичности запуска. Simple — традиционный способ, например, раз в 3 часа. А Crontab — это полноценная настройка крона, так сказать, в формате системного крона. Там вы можете указать например такую периодичность: 10 */2 * * 6,7. Эта запись означает, что будет происходить вызов крона «в десять минут каждого второго часа по субботам и воскресениям».

Ну и самое интересное — это реализация своих собственных заданий для крона.

Собственная задача для крона

Создадим свой модуль, файл azimut7_cron.info:

name = Azimut7 cron.
description = Custom cron task.
core=7.x
version = "7.x-1.0"
project = "azimut7_cron"

В файле модуля реализуем hook_cron с простейшим кодом. Будем просто добавлять запись в системный журнал.

azimut7_cron.module:

function azimut7_cron_cron() {
  watchdog('cron', 'My cron message');
}

Не забудьте включить модуль:

Теперь можно запустить крон через админку. Переходите по адресу admin/config/system/cron и жмите Run Cron.

После этого, в журнале по адресу admin/reports/dblog вы увидите свою запись (если её нет — проверьте, включен ли модуль Syslog, он входит в ядро).