systemd/Timers (Русский)

From ArchWiki
< Systemd(Redirected from Systemd/Tаймеры)
Jump to: navigation, search

Состояние перевода: На этой странице представлен перевод статьи Systemd/Timers. Дата последней синхронизации: 13 октября 2017. Вы можете помочь синхронизировать перевод, если в английской версии произошли изменения.

Таймеры - файлы служб systemd, имя которых оканчивается на .service, а также они контролируют файлы .service или события. И могут выступать альтернативой cron (смотрите #В качестве замены cron). Помимо этого имеют встроенную поддержку событий календаря, монотонных временных событий и могут быть запущены в асинхронном режиме.

Юниты таймера

Таймеры systemd - это файлы юнитов с суффиксом .timer. Они, как и другие файлы настроек юнитов, загружаются по одному и тому же пути, но включают в себя раздел [Timer]. Он определяет, как и когда таймер запускается. Таймер может быть одним из следующих двух типов:

  • Монотонные таймеры - активируются после определенного промежутка времени по отношению к той или иной отправной точки. Они не сработают, если компьютер находится в режиме ожидания или выключен. Есть несколько различных монотонных таймеров, но все они имеют вид: OnTypeSec=. OnBootSec и OnActiveSec являются общими монотонными таймерами.
  • Таймеры реального времени (также известный как настенные часы) - запускаются в зависимости от событий календаря (как cronjobs). Для определения таких таймеров используется опция OnCalendar=.

Для полного объяснения опций таймера смотрите systemd.timer(5). Синтаксис аргументов для событий календаря и промежутка времени смотрите в systemd.time(7).

Служба юнита

Каждому файлу .timer подходит соответствующий файл .service (например, foo.timer и foo.service). .timer запускается и контролирует .service. .service не требует раздела [Install], так как он присутствует в юните timer, который уже включен. Если необходимо, то можно контролировать юниты с разным названием, используя опцию Unit= в таймере в разделе [Timer].

Управление

Для того, чтобы использовать юнит timer, включите и запустите его, как любой другой юнит. (не забудьте добавить суффикс .timer). Для того, чтобы увидеть все запущенные таймеры, используйте:

$ systemctl list-timers
NEXT                          LEFT        LAST                          PASSED     UNIT                         ACTIVATES
Thu 2014-07-10 19:37:03 CEST  11h left    Wed 2014-07-09 19:37:03 CEST  12h ago    systemd-tmpfiles-clean.timer systemd-tmpfiles-clean.service
Fri 2014-07-11 00:00:00 CEST  15h left    Thu 2014-07-10 00:00:13 CEST  8h ago     logrotate.timer              logrotate.service
Примечание:
  • Чтобы увидеть все таймеры (в том числе и неактивные), используйте systemctl list-timers --all.
  • Статус сервиса, который запускается посредством таймера, вероятно, будет неактивным, если не сработает условие его запуска.
  • Если таймер рассинхронизировался, то может помочь удаление соответствующих файлов stamp-* в /var/lib/systemd/timers. Эти файлы, с нулевой длинной, которые отмечают последнее время, когда таймер был запущен. Если данные файлы отсутствуют, то они будут перестроены при следующем запуске соответствующего таймера.

Примеры

Юнит службы может быть запланирован с таймером. В следующем примере назначим запуск foo.service в соответствии с таймером foo.timer.

Монотонный таймер

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

/etc/systemd/system/foo.timer
[Unit]
Description=Run foo weekly and on boot

[Timer]
OnBootSec=15min
OnUnitActiveSec=1w 

[Install]
WantedBy=timers.target

Таймер в реальном времени

Таймер, который будет запускаться один раз в неделю (в 12:00 в понедельник). При активации он сразу же запустит службу, если отсутствует последнее время запуска (опция Persistent=true), например, в связи с отключением системы:

/etc/systemd/system/foo.timer
[Unit]
Description=Run foo weekly

[Timer]
OnCalendar=weekly
Persistent=true     
 
[Install]
WantedBy=timers.target

Если требуется указать более точную дату и время, используйте следующий формат:

ДеньНедели Год-Месяц-День Часы:Минуты:Секунды

Звездочка может быть использована, чтобы указать все значения, а запятые, в свою очередь, для перечисления возможных значений. Используйте .., чтобы выделить какой-то конкретный промежуток. В следующем примере сервис запускается в первые четыре дня каждого месяца в полдень, но только, если этими днями являются понедельник или вторник. Более подробная информация доступна в systemd.time(7).

OnCalendar=Mon,Tue *-*-01..04 12:00:00
Совет: Специальные выражения событий, такие как daily и weekly, относятся к конкретному времени начала и, таким образом, все таймеры, использующие эти выражения, запустятся одновременно. Таймеры, использующие специальные выражения, могут негативно сказаться на производительности системы, если сервисы, запускаемые таймерами, являются ресурсозатратными. Опция RandomizedDelaySec в разделе [Timer]помогает избежать подобных проблем посредством случайного выбора времени запуска каждого из таймеров. Смотрите systemd.timer(5).

Временные юниты .timer

Можно использовать systemd-run для создания временных юнитов .timer. То есть, можно назначить запуск определенной команды в нужно время, не имя файла сервиса. Например, следующая команда создаст файл через 30 секунд:

# systemd-run --on-active=30 /bin/touch /tmp/foo

Кроме того, можно указать предварительно существующий файл сервиса, при этом не имея файла таймера. Например, запустим юнит, который называется некоторыйюнит.service, через 12.5 часов:

# systemd-run --on-active="12h 30m" --unit некоторыйюнит.service

Смотрите systemd-run(1) для получения дополнительной информации и примеров.

В качестве замены cron

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

Преимущества

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

  • Задачи могут быть легко запущены независимо от их таймеров. Это упрощает отладку.
  • Каждая задача может быть настроена для работы в определенной среде (смотрите systemd.exec(5)).
  • Задачи могут быть присоединены к cgroups.
  • Задачи могут быть настроены в зависимости от других юнитов systemd.
  • Задачи регистрируются в журнале systemd для легкости отладки.

Предостережения

Некоторые вещи, которые легко сделать посредством cron, трудно сделать только юнитами таймера.

  • Создание: чтобы настроить задачу, запускаемую в определенное время, при помощи systemd, вам нужно создать два файла и использовать команды systemctl. Сравните это с добавлением одной строчки в crontab.
  • Электронная почта: отсутствие встроенного эквивалента cron MAILTO для отправки писем при сбое. В следующем разделе приведен пример создания эквивалента с использованием OnFailure=.

MAILTO

Вы можете настроить systemd для отправки электронной почты при сбое юнита - так же, как Cron делает с MAILTO. Прежде всего, нужно два файла: исполняемый для посылки почты и .service для запуска первого. В следующем примере, исполняемый файл - скрипт, использующий sendmail:

/usr/local/bin/systemd-email
#!/bin/bash

/usr/bin/sendmail -t <<ERRMAIL
To: $1
From: systemd <root@$HOSTNAME>
Subject: $2
Content-Transfer-Encoding: 8bit
Content-Type: text/plain; charset=UTF-8

$(systemctl status --full "$2")
ERRMAIL

В независимости от используемого выполняемого файла, вероятно, следует считывать по крайней мере два аргумента, как делает скрипт: адрес для отправки и файл юнита, чтобы получить его статус. Файл .service, который мы создадим, будет передавать следующие аргументы:

/etc/systemd/system/status-email-user@.service
[Unit]
Description=status email for %i to user

[Service]
Type=oneshot
ExecStart=/usr/local/bin/systemd-email address %i
User=nobody
Group=systemd-journal

Где user - получатель почты, а address - адрес электронной почты пользователя. Однако получателя изменить нельзя, потому что файл юнита передается как instance-параметр, то есть он может быть использован для отправки почты для других юнитов. Можете запустить status-email-user@dbus.service, чтобы убедиться в том, что вы можете получать почту.

Затем просто отредактируйте службу, о которой вы хотите получать почту и добавьте OnFailure=status-email-user@%n.service в раздел [Unit]. %n передает имя юнита в шаблон.

Примечание:
  • Если вы настроили SSMTP в соответствии с SSMTP#Security, то пользователь nobody не будет иметь доступа к /etc/ssmtp/ssmtp.conf и команда systemctl start status-email-user@dbus.service не сработает. Одним из решений является использование root, как Пользователь, в юните status-email-user@.service.
  • Если вы попробуете использовать mail -s somelogs address в почтовом скрипте, mail создаст свой форк и systemd убьет процесс посылки почты, когда увидит, что скрипт завершился. Можно сделать так, чтобы почтовый процесс не создавал своих форков путем выполнения mail -Ssendwait -s somelogs address.

Использование crontab

Некоторые из предостережений можно обойти путем установки пакета, который анализирует crontab, а затем настраивает таймеры на его основе. systemd-cron-nextAUR и systemd-cronAUR - два таких пакета. Они могут предоставлять недостающую функцию MAILTO.

Если вам нравится crontabs только потому, что он предоставляет единый вид для всех запланированных задач, systemctl делает тоже самое. Смотрите #Управление

Смотрите также

https://github.com/kstep/systemd-cron-next || systemd-cron-nextAUR
  • systemd-cron — предоставляет юнитам systemd запускать скрипты cron; используя systemd-crontab-generator для конвертации crontab'ов
https://github.com/systemd-cron/systemd-cron || systemd-cronAUR