Статьи

Планирование задач с помощью Cron Jobs

Задания Cron используются для планирования задач на сервере. Они чаще всего используются для автоматизации обслуживания или администрирования системы. Тем не менее, они также имеют отношение к разработке веб-приложений. Существует много ситуаций, когда веб-приложению могут потребоваться определенные задачи для периодического запуска. Сегодня мы собираемся исследовать основы Cron Jobs.

Для начала давайте ознакомимся с терминами, относящимися к этой теме.

«Cron» — это временный планировщик заданий в Unix-подобных операционных системах (Linux, FreeBSD, Mac OS и т. Д.). И эти задания или задания называются «Cron Jobs».

В этих системах работает cron «демон». Демон — это программа, которая все время работает в фоновом режиме, обычно запускаемая системой. Этот демон cron отвечает за запуск заданий cron по расписанию.

Расписание находится в файле конфигурации с именем «crontab». Вот где перечислены все задачи и их таймеры.

Администраторы сервера давно используют задания cron. Но поскольку целевой аудиторией этой статьи являются веб-разработчики, давайте рассмотрим несколько вариантов использования заданий cron, которые актуальны в этой области:

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

Вот простая работа cron:

1
10 * * * * /usr/bin/php /www/virtual/username/cron.php > /dev/null 2>&1

Есть две основные части:

  1. Первая часть «10 * * * *». Это где мы планируем таймер.
  2. Остальная часть строки — это команда, которая запускается из командной строки.

Сама команда в этом примере состоит из трех частей:

  1. «/ USR / бен / PHP». Сценарии PHP обычно не выполняются сами по себе. Поэтому нам нужно запустить его через анализатор PHP.
  2. «/Www/virtual/username/cron.php». Это просто путь к сценарию.
  3. «> / dev / null 2> & 1». Эта часть обрабатывает вывод скрипта. Подробнее об этом позже.

Это первая часть строки работы cron, как упоминалось выше. Он определяет, как часто и когда будет выполняться задание cron.

Он состоит из пяти частей:

  1. минут
  2. час
  3. день месяца
  4. месяц
  5. день недели

Вот иллюстрация:

Довольно часто вы увидите звездочку (*) вместо числа. Это представляет все возможные числа для этой позиции. Например, звездочка в минутной позиции запускает каждую минуту.

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

Эта работа cron будет выполняться каждую минуту, все время:

1
* * * * * [command]

Это задание cron будет выполняться в ноль минут каждый час (т. Е. Ежечасное задание cron):

1
0 * * * * [command]

Это также почасовая работа cron, но вместо этого она запускается на 15 минуте (т.е. 00:15, 01:15, 02:15 и т. Д.):

1
15 * * * * [command]

Это будет выполняться один раз в день, в 2:30:

1
30 2 * * * [command]

Это будет выполняться один раз в месяц, во второй день месяца в полночь (т.е. 2 января, 12:00, 2 февраля, 12:00 и т. Д.):

1
0 0 2 * * [command]

Это будет выполняться по понедельникам, каждый час (то есть 24 раза в день, но только по понедельникам):

1
0 * * * 1 [command]

Вы можете использовать несколько номеров, разделенных запятыми. Это будет выполняться три раза каждый час, в минуты 0, 10 и 20:

1
0,10,20 * * * * [command]

Оператор деления также используется. Это будет выполняться 12 раз в час, т.е. каждые 5 минут:

1
*/5 * * * * [command]

Тире можно использовать для указания диапазона. Это будет выполняться один раз в час с 5:00 до 10:00:

1
0 5-10 * * * [command]

Также есть специальное ключевое слово, которое позволит вам запускать задание cron каждый раз при перезагрузке сервера:

1
@reboot [command]

Есть несколько разных способов создания и управления вашими заданиями cron.

Многие веб-хостинги предоставляют панели управления для своих клиентов. Если вы один из них, вы можете найти раздел на панели управления для управления заданиями cron.

Выполнение этой команды запустит vi (текстовый редактор) и позволит вам отредактировать содержимое crontab:

1
crontab -e

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

Если вы просто хотите увидеть существующий crontab, не редактируя его, вы можете запустить эту команду:

1
crontab -l

Чтобы удалить содержимое crontab:

1
crontab -r

Вы можете записать все свои задания cron в файл и затем поместить его в crontab:

1
crontab cron.txt

Будьте осторожны, потому что это перезапишет все существующие задания cron с содержимым этих файлов без предупреждения.

Вы можете добавить комментарии с последующим символом #.

1
2
# This cron job does something very important
10 * * * * /usr/bin/php /www/virtual/username/cron.php > /dev/null 2>&1

Как я упоминал ранее, по умолчанию выходные данные crons отправляются по электронной почте, если вы не отбросите их или не перенаправите в файл. Параметр MAILTO позволяет установить или изменить адрес электронной почты, на который они будут отправляться:

1
2
3
# This cron job does something very important
10 * * * * /usr/bin/php /www/virtual/username/cron.php > /dev/null 2>&1

Сценарии CGI исполняются по умолчанию, а сценарии PHP — нет. Они должны работать через анализатор PHP. Вот почему нам нужно поставить путь к парсеру перед путем скрипта.

1
* * * * * /usr/bin/php [path to php script]

Иногда это может быть в другом месте, например: «/ usr / local / bin / php». Чтобы выяснить это, вы можете попробовать запустить это в командной строке:

1
which php

Если вы не обрабатываете вывод скрипта cron, он отправит их по электронной почте на вашу учетную запись на сервере.

Если вы поставите «> / dev / null 2> & 1» в конце команды задания cron (или любой другой команды), вывод будет отброшен.

Закрывающая скобка (>) используется для перенаправления вывода. «/ dev / null» похож на черную дыру для вывода. Все, что идет туда, игнорируется системой.

Эта часть «2> & 1» приводит к тому, что выход STDERR (ошибка) перенаправляется на выход STDOUT (нормальный). Так что это также заканчивается в «/ dev / null».

Чтобы сохранить вывод cron в файле, снова используйте закрывающую скобку (>):

1
10 * * * * /usr/bin/php /www/virtual/username/cron.php > /var/log/cron.log

Это будет перезаписывать выходной файл каждый раз. Если вы хотите добавить вывод в конец файла вместо полной перезаписи, используйте вместо этого двойную закрывающую скобку (>>):

1
10 * * * * /usr/bin/php /www/virtual/username/cron.php >> /var/log/cron.log

Обычно вам нужно указать синтаксический анализатор в начале команды, как мы это делали. Но на самом деле есть способ сделать ваши PHP-скрипты исполняемыми из командной строки, как CGI-скрипт.

Вам нужно добавить путь к парсеру в качестве первой строки скрипта:

1
2
3
4
5
6
7
8
#!/usr/local/bin/php
<?php
 
echo «hello world\n»;
 
// …
 
?>

Также убедитесь, что вы установили правильный chmod (например, 755), чтобы сделать файл исполняемым.

Когда у вас есть исполняемый скрипт, задание cron может быть короче, например так:

1
10 * * * * /www/virtual/username/hello.php

В некоторых случаях вы можете часто запускать задания cron, и вы можете не захотеть, чтобы они сталкивались, если они работают дольше, чем сама частота.

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

Эта проблема может быть решена с помощью блокировки файлов и, в частности, неблокирующих (LOCK_NB) типов блокировок файлов. (Если вы не знакомы с блокировкой файлов, я предлагаю вам сначала прочитать об этом .)

Вы можете добавить этот код в скрипт задания cron:

01
02
03
04
05
06
07
08
09
10
$fp = fopen(‘/tmp/lock.txt’, ‘r+’);
 
if(!flock($fp, LOCK_EX | LOCK_NB)) {
    echo ‘Unable to obtain lock’;
    exit(-1);
}
 
/* … */
 
fclose($fp);

При обычных блокировках файлов вызов функции flock () блокирует скрипт, если существует существующая блокировка. И он освободится, как только этот замок исчезнет. Однако с неблокирующей блокировкой, такой как в приведенном выше коде, вызов функции не останавливает сценарий, а немедленно возвращает FALSE, если существует существующая блокировка. Таким образом, в этом случае мы можем немедленно выйти из скрипта, когда увидим, что существует существующая блокировка, которая указывает, что в настоящий момент выполняется другое задание cron.

Когда вы пишете работу cron на языке веб-сценариев, таком как PHP, вы можете быть уверены, что никто не сможет выполнить его, просто загрузив его из браузера. Один из простых вариантов — хранить эти скрипты вне вашей веб-папки. Однако это может быть непрактичным или предпочтительным для некоторых разработчиков, если они хотят хранить свои скрипты работы cron прямо в папках своего веб-приложения.

Если вы поместите все сценарии заданий cron в папку, вы заблокируете доступ, поместив эту строку в файл .htaccess:

1
deny from all

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

1
if (isset($_SERVER[‘REMOTE_ADDR’])) die(‘Permission denied.’);

Это гарантирует, что при доступе к сценарию из Интернета он будет немедленно прерван.

Спасибо за чтение. Несмотря на то, что задания cron кажутся инструментами только для системных администраторов, на самом деле они актуальны для многих видов веб-приложений.

Пожалуйста, оставляйте свои комментарии и вопросы, и хорошего дня!

Знаете ли вы, что вы можете заработать до 600 долларов за написание учебника PLUS и / или скринкаст для нас? Мы ищем подробные и хорошо написанные учебники по HTML, CSS, PHP и JavaScript. Если у вас есть такая возможность, пожалуйста, свяжитесь с Джеффри по адресу [email protected].

Обратите внимание, что фактическая компенсация будет зависеть от качества окончательного урока и скринкаста.

Написать ПЛЮС учебник
  • Подпишитесь на нас в Твиттере или подпишитесь на ленту Nettuts + RSS для получения лучших учебных материалов по веб-разработке.