# Настройка и управление cron-задачами

Source: https://support.kapsulehost.com/ru-ru/cron-jobs

Задача cron выполняет команду по расписанию, в фоновом режиме, независимо от того, заходит ли кто-то на ваш сайт в этот момент. В этом руководстве описано, как добавить такую задачу в KPanel, как правильно написать расписание и команду для этой платформы, как заменить ненадёжный встроенный планировщик WordPress, и как найти вывод, если задача делает не то, что вы ожидали.

## Где находится Cron в KPanel

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

1. Войдите в [KPanel](https://kpanel.kapsulehost.com) и нажмите **Веб-сайты** в левой боковой панели.
2. Нажмите на нужный сайт.
3. В меню сайта откройте **Параметры**, затем **Cron**.

Прямой адрес: `/websites/<site-id>/cron`. Вы увидите таблицу существующих задач или пустое состояние, если на сайте их ещё нет.

![Страница Cron для сайта в KPanel со списком запланированных задач на этом сайте](https://support.kapsulehost.com/help/screenshots/cron-jobs.13aef775.webp)

## Добавление задачи

Нажмите **Добавить задачу Cron** в правом верхнем углу. Форма содержит три поля.

### Расписание

Шесть готовых кнопок заполняют выражение за вас:

| Кнопка | Выражение |
|---|---|
| Каждую минуту | `* * * * *` |
| Каждые 5 мин | `*/5 * * * *` |
| Каждый час | `0 * * * *` |
| Ежедневно 2:00 | `0 2 * * *` |
| Еженедельно воскресенье | `0 2 * * 0` |
| Ежемесячно 1-е число | `0 2 1 * *` |

Либо впишите своё собственное в поле **Выражение Cron**. Пять полей, по порядку: минута, час, день месяца, месяц, день недели:

```
minute  hour  day-of-month  month  day-of-week
```

- `0 3 * * *` запускается в 3:00 каждый день.
- `*/15 * * * *` запускается каждые пятнадцать минут.
- `0 9 * * 1` запускается в 9:00 каждый понедельник.
- `30 1 1 * *` запускается в 1:30 первого числа каждого месяца.
- `0 */6 * * *` запускается каждые шесть часов, ровно в начале часа.

### Метка

Название, которое вы узнаете позже, например `WordPress cron` или `Nightly stock sync`. Именно его показывает таблица задач, поэтому делайте его описательным: `job 3` никому не поможет в 2 часа ночи.

### Команда

Команда оболочки, которая будет выполняться. Нажмите **Save**, чтобы создать задачу.

> **Warning:** Используйте полные пути. Cron выполняется в минимальном окружении, без вашего профиля оболочки, поэтому голая `php` или относительный путь, который работает, когда вы залогинены по SSH, здесь будет молча давать сбой. Прописывайте полный путь каждый раз.

## Написание команды

Задачи выполняются от имени системного пользователя вашего сайта, поэтому ваш домашний каталог служит правильным ориентиром, и `~` разрешается корректно. Файлы вашего сайта находятся по пути:

```
~/htdocs/yourdomain.co.nz
```

Вы можете уточнить точный путь на вкладке **Параметры**, затем **SFTP** сайта: он выводится под **Файлы сайта**.

Типичные команды:

```
cd ~/htdocs/yourdomain.co.nz && /usr/bin/wp cron event run --due-now
```

```
cd ~/htdocs/yourdomain.co.nz && /usr/bin/php bin/send-queued-emails.php
```

```
/usr/bin/curl -fsS https://yourdomain.co.nz/api/nightly-report
```

> **Tip:** Проверьте команду, прежде чем ставить её в расписание. Вставьте её в раздел **WordPress**, затем **Console** сайта, если это команда `wp`, либо выполните её по SSH. Задачу, которая никогда не заработает, гораздо легче заметить в командной строке, чем в логе в 3 часа ночи.

## Замена встроенного планировщика WordPress

WordPress поставляется с собственным псевдо-планировщиком, WP-Cron, который срабатывает только тогда, когда кто-то загружает страницу. На тихом сайте запланированные записи публикуются с опозданием, а письма копятся неотправленными. На загруженном сайте каждый посетитель оплачивает своим временем проверку расписания.

Настоящая задача cron решает обе проблемы. KPanel делает всю замену за вас:

1. Откройте сайт, затем вкладку **WordPress**.
2. Откройте раздел **WP-Cron**.
3. Нажмите **Включить системный cron**.

Это добавляет расписание, которое запускает WP-Cron каждые пять минут, и устанавливает `DISABLE_WP_CRON`, чтобы загрузки страниц больше не вызывали его. **Удалить системный cron** на том же экране отменяет обе половины.

Если вы предпочитаете сделать это вручную, это два шага:

**Отключите версию, запускаемую посетителями.** Добавьте это в `wp-config.php`, над строкой `/* That's all, stop editing! */`, используя **Параметры**, затем **Менеджер файлов**:

```php
define( 'DISABLE_WP_CRON', true );
```

**Добавьте настоящую задачу.** В **Параметры**, затем **Cron**:

- Расписание: `*/5 * * * *`
- Метка: `WordPress cron`
- Команда: `cd ~/htdocs/yourdomain.co.nz && /usr/bin/wp cron event run --due-now`

> **Warning:** Не пропускайте половину с `DISABLE_WP_CRON`. Если работают обе, каждая запланированная задача может сработать дважды: дублирующиеся письма, дублирующаяся обработка заказов, дублирующиеся списания в плагине подписок. Используйте однократное действие в разделе WP-Cron, и с вами такого не случится.

## WooCommerce и фоновые очереди

WooCommerce использует фоновую очередь для изменений статуса заказов, продления подписок, писем и обновлений остатков. Она полагается на WP-Cron, и это как раз та нагрузка, которая страдает на тихом магазине.

Как только настоящее расписание настроено, очередь обрабатывается каждые пять минут. Следите за ней в wp-admin: **WooCommerce**, затем **Status**, затем **Scheduled Actions**.

Магазин с большим объёмом трафика может перейти на `*/2 * * * *`. Снижать это значение дальше обычно бесполезно: вы тратите больше времени на запуск процессов, чем на саму работу. См. [Настройка WooCommerce](https://support.kapsulehost.com/ru-ru/wordpress-woocommerce).

## Управление существующими задачами

Таблица задач показывает **Label**, **Schedule**, **Command**, **Последний запуск** и **Status**, с двумя действиями в каждой строке:

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

> **Important:** Удаление задачи cron нельзя отменить. Расписание удаляется с сервера сразу же. Если вы хотите только временно остановить задачу, используйте **Disable**.

## Поиск вывода

Для каждой задачи, созданной KapsuleHost, вывод автоматически сохраняется. Стандартный вывод и ошибки дописываются в файл лога в каталоге `cron-logs` в домашнем каталоге пользователя вашего сайта, по одному файлу на задачу.

Этот лог отвечает почти на любой вопрос "выполнилась ли моя задача?", потому что в нём записано, что вывела команда, и любая возникшая ошибка.

Чтобы прочитать его, подключитесь по SSH и посмотрите в `~/cron-logs/`. SSH использует аутентификацию по ключу, поэтому сначала добавьте свой открытый ключ на вкладке **Параметры**, затем **SSH-ключи** сайта: см. [Добавление SSH-ключей](https://support.kapsulehost.com/ru-ru/adding-ssh-keys).

> **Note:** Учётные записи Менеджера файлов и SFTP ограничены каталогом вашего сайта, `~/htdocs/yourdomain.co.nz`, а `cron-logs` находится на один уровень выше. Это сделано намеренно: это не даёт подрядчику с доступом по SFTP добраться до чего-либо, кроме самого сайта. Используйте нативный SSH для доступа к логам или перенаправляйте вывод в каталог вашего сайта, как показано ниже.

Если вы хотите, чтобы вывод оказывался там, где его сможет открыть Менеджер файлов, перенаправьте его самостоятельно:

```
cd ~/htdocs/yourdomain.co.nz && /usr/bin/wp cron event run --due-now >> ~/htdocs/yourdomain.co.nz/wp-content/cron.log 2>&1
```

`2>&1` отправляет ошибки в тот же файл, что и обычный вывод. Без этого ошибки уходят в никуда.

> **Warning:** Всё, что находится внутри каталога вашего сайта, потенциально может быть запрошено через веб. Размещайте перенаправленный лог под `wp-content`, а не в корне сайта, давайте ему имя, которое никто не угадает, и удаляйте его, как только закончите отладку.

## Рекомендации

- **Распределяйте расписания по времени.** Шесть задач, установленных на `0 2 * * *`, запустятся все разом. Разнесите их: `0 2`, `10 2`, `20 2`.
- **Не используйте запуск каждую минуту без реальной необходимости.** `*/5` достаточно почти для всего, включая WordPress и WooCommerce.
- **Делайте задачи короткими.** Задача, которая выполняется дольше своего интервала, будет пересекаться со следующим запуском.
- **Перенаправляйте вывод для всего, что шумит**, чтобы одна болтливая задача не заполнила весь диск.
- **Периодически просматривайте список.** Задачи, оставшиеся от удалённого плагина, продолжают выполняться.

## Устранение неполадок

**Задача, кажется, никогда не выполняется.** Сначала проверьте путь. Откройте файл лога. Затем убедитесь, что статус **Active**, а не **Disabled**. Затем выполните ту же команду по SSH и посмотрите, что она выдаст.

**В логе "command not found".** Отсутствует полный путь. Используйте `/usr/bin/php`, `/usr/bin/wp`, `/usr/bin/curl` вместо голого имени.

**Permission denied.** Задача выполняется от имени системного пользователя вашего сайта. Этому пользователю нужно владеть, или хотя бы иметь возможность читать, всё, к чему обращается команда. Проверьте права доступа в статье [Использование Менеджера файлов](https://support.kapsulehost.com/ru-ru/file-manager).

**Задачи WordPress по-прежнему выполняются с опозданием.** Убедитесь, что обе половины замены на месте: расписание существует в **Параметры**, затем **Cron**, и установлен `DISABLE_WP_CRON`. Раздел **WP-Cron** на вкладке **WordPress** показывает текущее состояние обеих половин.

**Задача выполняется, но во время её работы сайт работает медленно.** Перенесите её на более тихий час или разбейте работу на меньшие порции. Использование ресурсов на уровне сайта видно в разделе **Производительность**: см. [Повышение скорости сайта](https://support.kapsulehost.com/ru-ru/website-speed).

**Задача перестала работать после обновления плагина.** Возможно, изменился путь к команде. Проверьте лог, затем обновите команду в таблице задач, удалив старую задачу и добавив исправленную.
