БыстраяЗаменаCrontabНаTimers: различия между версиями

Материал из ALT Linux Wiki
м (...судя по свежим правкам...)
Метка: новое перенаправление
 
(не показано 36 промежуточных версий 2 участников)
Строка 1: Строка 1:
{{span|font-size: 180%|Простая замена crontab'ов на таймеры systemd}}
#REDIRECT [[Таймеры systemd вместо crond]]
==Предмет статьи==
Речь о периодических задачах, которые следует исполнять еже<…>но, без указания сложных конструкций из даты:времени/периодичности (сиречь, о том, чем занимаются скрипты из /etc/cron.<…>ly/, плюс не охваченные ими ежеминутные, ежеквартальные и ежесеместровые запуски).
==Варианты==
В части руководств встречаются рекомендации пилить таймеры под каждый отдельный юнит, существуют и генераторы таймеров на основе crontab - проекты некоторых можно глянуть [https://github.com/systemd-cron здесь].
Но мне они показались несколько выморочными, чересчур навороченными - ведь всё необходимое уже наличествует в systemd, и следует признать: находились таки примеры с таймерами/таргетами на отдельные периоды - часы/дни/недели и т.п.
 
Но посредством шаблонов можно сделать проще
 
==Реализация==
===Запилил пару шаблонов===
 
<code># cat /lib/systemd/system/doit@.timer</code> (для периодических таймеров)
<source lang="ini">
[Unit]
Description = %i timer
 
[Timer]
OnCalendar = %i
Persistent = true
Unit = doit@%i.target
 
[Install]
WantedBy = timers.target
</source>
<code># cat /lib/systemd/system/doit@.target</code> (для их «целей»)
<source lang="ini">
[Unit]
Description = %i timer target
StopWhenUnneeded = yes
</source>
doit - мол, «делать это еже…»
<pre>
minutely      …минутно,
hourly        …часно,
daily        …дневно,
weekly        …недельно,
monhly        …месячно,
quarter      …квартально,
semi-annually …семестрово,
yearly        …годно.
</pre>
Само собой, «doit» что в именах, что в шаблоне таймера и периодически запускаемых сервисах можно заменить на «do», «run», «cron», «timers» или что угодно иное.
 
===Включил и запустил периодические таймеры===
<source lang="bash">
for ACT in enable start; do
    systemctl $ACT doit@{minute,hour,dai,week,month,quarter,semi-annual,year}ly.timer
done
</source>
===Создал сервисы, требующие периодического исполнения===
Пример нашёл на просторах интернетов, нужную периодичность указал через секцию [Install]:
 
<code># cat /lib/systemd/system/logrotate.service</code>
<source lang="ini">
[Unit]
Description = Rotate system logs
 
[Service]
Nice = 19
Type = simple
IOSchedulingClass = 2
IOSchedulingPriority = 7
ExecStart = /usr/sbin/logrotate /etc/logrotate.conf
 
[Install]
WantedBy = doit@daily.target
</source>
 
===И, наконец, включил их===
<code># systemctl enable <список таких сервисов></code>
 
…напоследок проверив, что юниты нужных сервисов активированы:
 
<code># ls /etc/systemd/system/doit@{minute,dai,month}ly.target.wants</code>
<pre>
/etc/systemd/system/doit@daily.target.wants:
logrotate.service
 
/etc/systemd/system/doit@minutely.target.wants:
unbound-stats.service
 
/etc/systemd/system/doit@monthly.target.wants:
unbound-anchor.service
</pre>
===Собственно, готово - работает===
Вот:
 
<code># systemctl list-timers</code>
<pre>
Wed 2017-12-20 12:28:00 IRKT  22s left            Wed 2017-12-20 12:27:00 IRKT  37s ago              doit@minutely.timer          doit@minutely.target
Wed 2017-12-20 13:00:00 IRKT  32min left          Wed 2017-12-20 12:00:00 IRKT  27min ago            doit@hourly.timer            doit@hourly.target
Thu 2017-12-21 00:00:00 IRKT  11h left            Wed 2017-12-20 00:00:18 IRKT  12h ago              doit@daily.timer            doit@daily.target
Thu 2017-12-21 11:12:16 IRKT  22h left            Wed 2017-12-20 11:12:16 IRKT  1h 15min ago        systemd-tmpfiles-clean.timer systemd-tmpfiles-clean.service
Mon 2017-12-25 00:00:00 IRKT  4 days left        Mon 2017-12-18 00:00:00 IRKT  2 days ago          doit@weekly.timer            doit@weekly.target
Mon 2018-01-01 00:00:00 IRKT  1 weeks 4 days left Fri 2017-12-01 00:00:00 IRKT  2 weeks 5 days ago  doit@monthly.timer          doit@monthly.target
Mon 2018-01-01 00:00:00 IRKT  1 weeks 4 days left n/a                          n/a                  doit@quarterly.timer        doit@quarterly.target
Mon 2018-01-01 00:00:00 IRKT  1 weeks 4 days left n/a                          n/a                  doit@semi-annually.timer    doit@semi-annually.target
Mon 2018-01-01 00:00:00 IRKT  1 weeks 4 days left Tue 2017-10-24 18:17:11 IRKT  1 months 26 days ago doit@yearly.timer            doit@yearly.target
 
9 timers listed.
Pass --all to see loaded but inactive timers, too.
</pre>
 
Можно выключить крон:
 
<code># for ACT in stop disable; do systemctl $ACT crond; done</code>
 
И не беда, что реально работают меньше половины таймеров: один предустановленный и три добавленных, а остальные пять - пустышки. Лишние можно отключить либо рассматривать их как заготовки - вроде пустых каталогов среди /etc/cron.<…>ly/.
==Примечание==
Само собой, для сложных конструкций в замену кронтабов из /etc/cron.d/ придётся создавать отдельные таймеры, которые, однако, справятся и там, где крон нужно подпирать костылём - вроде проверки программного RAID-массива:
 
<code>57 0 * * 0 root [ -x /usr/share/mdadm/checkarray ] && [ $(date +\%d) -le 7 ] && /usr/share/mdadm/checkarray --cron --all --idle --quiet</code>
 
Данный пример его автор комментирует так: ''Запускать задачу следует по воскресеньям, но не позже 7-го числа - то есть, лишь в первое воскресенье каждого месяца, в каковой ситуации кронтаб беспомощен, так что приходится пользовать хак.''
 
И вот наипростейший пример таймера, который будет запускаться пусть не в первое, а в последнее воскресенье месяца, но без плясок с бубном из скриптов:
<source lang="ini">
[Unit]
Description = Last Monday of month timer
 
[Timer]
OnCalendar = Sun *~07/1
Persistent = true
 
[Install]
WantedBy = timers.target
</source>
[[Категория:Admin]]
{{Category navigation|title=Системному администратору|category=Admin|sortkey={{SUBPAGENAME}}}}

Текущая версия от 17:09, 3 октября 2020

Перенаправление на: