Advertisement
  1. Code
  2. Coding Fundamentals
  3. Terminal and CLI

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

Scroll to top

() translation by (you can also view the original English article)

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

Определения

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

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

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

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

Зачем Использовать Cron?

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

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

Синтаксис

Вот простое задание cron:

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

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

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

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

  1. "/usr/bin/php". PHP-скрипты обычно не исполняются сами по себе. Поэтому нам нужно запустить его через интерпретатор PHP.
  2. "/www/virtual/username/cron.php". Это просто путь к скрипту.
  3. "> /dev/null 2>&1". Эта часть обрабатывает вывод скрипта. Подробнее об этом позже.

Синтаксис тайминга

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

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

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

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

Звездочка

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

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

Примеры:

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

1
2
* * * * * [command]

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

1
2
0 * * * * [command]

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

1
2
15 * * * * [command]

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

1
2
30 2 * * * [command]

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

1
2
0 0 2 * * [command]

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

1
2
0 * * * 1 [command]

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

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

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

1
2
*/5 * * * * [command]

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

1
2
0 5-10 * * * [command]

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

1
2
@reboot [command]

Настройка и управление заданиями Cron

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

Панели управления

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

Редактирование crontab

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

1
2
crontab -e

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

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

1
2
crontab -l

Удаление содержимого crontab:

1
2
crontab -r

Загрузка файла

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

1
2
crontab cron.txt

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

Комментарии

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

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

Настройка электронной почты

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

1
2
MAILTO="username@example.com"
3
# This cron job does something very important
4
10 * * * * /usr/bin/php /www/virtual/username/cron.php > /dev/null 2>&1

Использование PHP интерпретатора

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

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

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

1
2
which php

Обработка выходных данных

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

Отбрасывание Вывода

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

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

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

Вывод в файл

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

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

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

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

Исполняемые скрипты

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

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

1
2
#!/usr/local/bin/php
3
<?php
4
5
echo "hello world\n";
6
7
// ...

8
9
?>

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

При наличии исполняемого сценария задание cron может быть короче:

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

Предотвращение конфликтов заданий Cron

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

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

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

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

1
2
$fp = fopen('/tmp/lock.txt', 'r+');
3
4
if(!flock($fp, LOCK_EX | LOCK_NB)) {
5
    echo 'Unable to obtain lock';
6
    exit(-1);
7
}
8
9
/* ... */
10
11
fclose($fp);

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

Блокировка веб-доступа к заданиям cron

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

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

1
2
deny from all

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

1
2
3
if (isset($_SERVER['REMOTE_ADDR'])) die('Permission denied.');

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

Заключение

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

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

Напишите учебник

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

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

Write a PLUS tutorial
  • Следите за нами в Twitter, или подпишитесь на канал Nettuts+ RSS для получения лучших учебников веб-разработки в интернете.
Advertisement
Did you find this post useful?
Want a weekly email summary?
Subscribe below and we’ll send you a weekly email summary of all new Code tutorials. Never miss out on learning about the next big thing.
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.