Usando timers systemd em vez de cron jobs

No momento, estou substituindo meus trabalhos do cron por cronômetros do systemd. Tenho usado cronômetros há vários anos, mas normalmente não me aprofundei nas complexidades de seu uso, descobrindo apenas o que era necessário para completar a tarefa de meu interesse. Recentemente, trabalhei em uma série de artigos sobre o systemd e descobri que os temporizadores do systemd têm alguns recursos muito interessantes.







Esses cronômetros, como os cron jobs, podem, em um determinado momento, acionar várias ações no sistema. Por exemplo - executando scripts de shell ou programas. Os cronômetros podem funcionar, por exemplo, uma vez por dia e apenas às segundas-feiras. Outro exemplo é um cronômetro que dispara a cada 15 minutos durante o horário comercial (das 8h às 18h). Mas os cronômetros do systemd podem fazer algo que os cron jobs não podem. Por exemplo, um cronômetro pode chamar um script ou programar um tempo específico após um evento. Tal evento pode ser a inicialização do sistema ou inicialização do systemd, a conclusão de uma tarefa anterior ou até mesmo o encerramento de um serviço que foi anteriormente chamado por um cronômetro.



Temporizadores usados ​​para manutenção do sistema



Quando o Fedora ou outra distribuição Linux baseada em systemd é instalada em um computador, vários cronômetros são criados como parte das rotinas de manutenção do sistema. Esses procedimentos são executados automaticamente em qualquer sistema Linux. Os cronômetros correspondentes acionam várias tarefas de serviço, como atualização de bancos de dados do sistema, limpeza de diretórios temporários, rotação de arquivos de log e assim por diante.



Como exemplo, darei aqui informações sobre os temporizadores que estão disponíveis na máquina virtual que usei para os experimentos. Aqui, para obter uma lista de todos os temporizadores, usei o comandosystemctl status *timer... O curinga asterisco desempenha a mesma função aqui e em outros comandos semelhantes. Ou seja, ele informa ao sistema que estamos interessados ​​em todos os cronômetros (unidades de cronômetro, também chamados de "arquivos de unidade de cronômetro" ou "unidades de cronômetro") do systemd:



[root@testvm1 ~]# systemctl status *timer
● mlocate-updatedb.timer - Updates mlocate database every day
     Loaded: loaded (/usr/lib/systemd/system/mlocate-updatedb.timer; enabled; vendor preset: enabled)
     Active: active (waiting) since Tue 2020-06-02 08:02:33 EDT; 2 days ago
    Trigger: Fri 2020-06-05 00:00:00 EDT; 15h left
   Triggers: ● mlocate-updatedb.service

Jun 02 08:02:33 testvm1.both.org systemd[1]: Started Updates mlocate database every day.

● logrotate.timer - Daily rotation of log files
     Loaded: loaded (/usr/lib/systemd/system/logrotate.timer; enabled; vendor preset: enabled)
     Active: active (waiting) since Tue 2020-06-02 08:02:33 EDT; 2 days ago
    Trigger: Fri 2020-06-05 00:00:00 EDT; 15h left
   Triggers: ● logrotate.service
       Docs: man:logrotate(8)
             man:logrotate.conf(5)

Jun 02 08:02:33 testvm1.both.org systemd[1]: Started Daily rotation of log files.

● sysstat-summary.timer - Generate summary of yesterday's process accounting
     Loaded: loaded (/usr/lib/systemd/system/sysstat-summary.timer; enabled; vendor preset: enabled)
     Active: active (waiting) since Tue 2020-06-02 08:02:33 EDT; 2 days ago
    Trigger: Fri 2020-06-05 00:07:00 EDT; 15h left
   Triggers: ● sysstat-summary.service

Jun 02 08:02:33 testvm1.both.org systemd[1]: Started Generate summary of yesterday's process accounting.

● fstrim.timer - Discard unused blocks once a week
     Loaded: loaded (/usr/lib/systemd/system/fstrim.timer; enabled; vendor preset: enabled)
     Active: active (waiting) since Tue 2020-06-02 08:02:33 EDT; 2 days ago
    Trigger: Mon 2020-06-08 00:00:00 EDT; 3 days left
   Triggers: ● fstrim.service
       Docs: man:fstrim

Jun 02 08:02:33 testvm1.both.org systemd[1]: Started Discard unused blocks once a week.

● sysstat-collect.timer - Run system activity accounting tool every 10 minutes
     Loaded: loaded (/usr/lib/systemd/system/sysstat-collect.timer; enabled; vendor preset: enabled)
     Active: active (waiting) since Tue 2020-06-02 08:02:33 EDT; 2 days ago
    Trigger: Thu 2020-06-04 08:50:00 EDT; 41s left
   Triggers: ● sysstat-collect.service

Jun 02 08:02:33 testvm1.both.org systemd[1]: Started Run system activity accounting tool every 10 minutes.

● dnf-makecache.timer - dnf makecache --timer
     Loaded: loaded (/usr/lib/systemd/system/dnf-makecache.timer; enabled; vendor preset: enabled)
     Active: active (waiting) since Tue 2020-06-02 08:02:33 EDT; 2 days ago
    Trigger: Thu 2020-06-04 08:51:00 EDT; 1min 41s left
   Triggers: ● dnf-makecache.service

Jun 02 08:02:33 testvm1.both.org systemd[1]: Started dnf makecache –timer.

● systemd-tmpfiles-clean.timer - Daily Cleanup of Temporary Directories
     Loaded: loaded (/usr/lib/systemd/system/systemd-tmpfiles-clean.timer; static; vendor preset: disabled)
     Active: active (waiting) since Tue 2020-06-02 08:02:33 EDT; 2 days ago
    Trigger: Fri 2020-06-05 08:19:00 EDT; 23h left
   Triggers: ● systemd-tmpfiles-clean.service
       Docs: man:tmpfiles.d(5)
             man:systemd-tmpfiles(8)

Jun 02 08:02:33 testvm1.both.org systemd[1]: Started Daily Cleanup of Temporary Directories.


Cada cronômetro está associado a pelo menos seis linhas contendo informações sobre ele:



  • A primeira linha contém o nome do arquivo do cronômetro e uma breve descrição do propósito da existência do cronômetro.
  • A segunda linha exibe informações sobre o estado do cronômetro. Ou seja, ele relata se está carregado, fornece o caminho completo para o arquivo do cronômetro, mostra o estado da predefinição do fornecedor (desativado ou ativado).
  • A terceira linha mostra informações sobre a atividade do cronômetro, que inclui informações sobre quando o cronômetro foi ativado.
  • A quarta linha contém a data e a hora da próxima inicialização do cronômetro e o tempo aproximado restante até ele iniciar.
  • A quinta linha fornece o nome do serviço ou evento chamado pelo cronômetro.
  • Alguns (mas não todos) arquivos de unidade de cronômetro do systemd contêm indicações para documentação. Esses ponteiros estão, no meu exemplo, nas descrições de três temporizadores.
  • A última linha na descrição do cronômetro é a entrada de registro associada à instância mais recente do serviço chamado pelo cronômetro.


Se você tentar executar um comando em seu computador systemctl status *timer, o conjunto de temporizadores apresentado a ele pode ser diferente do meu.



Criação de cronômetro



Embora possamos entender os detalhes de como os temporizadores funcionam analisando quaisquer temporizadores existentes, sugiro criar seu próprio arquivo de unidade de serviço (arquivo de configuração de serviço , unidade de serviço ) e um arquivo de temporizador com o qual o serviço correspondente será chamado. Estamos aqui, para não complicar a história, dar um exemplo bastante trivial. Mas depois de lidarmos com isso, será mais fácil para você entender o trabalho de outros cronômetros.



Primeiro, vamos criar um arquivo de configuração de serviço simples que executará algo tão simples quanto um comando free. Por exemplo, isso pode ser necessário se precisarmos monitorar regularmente a quantidade de memória livre. Vamos criar um arquivo de unidade nomeado myMonitor.servicena pasta /etc/systemd/system. Não precisa ser executável.



# This service unit is for testing timer units
# By David Both
# Licensed under GPL V2
#

[Unit]
Description=Logs system statistics to the systemd journal
Wants=myMonitor.timer

[Service]
Type=oneshot
ExecStart=/usr/bin/free

[Install]
WantedBy=multi-user.target


Este arquivo é provavelmente o arquivo de configuração de serviço mais simples. Agora vamos verificar seu status e testá-lo para ter certeza de que funciona conforme o esperado.



[root@testvm1 system]# systemctl status myMonitor.service
● myMonitor.service - Logs system statistics to the systemd journal
     Loaded: loaded (/etc/systemd/system/myMonitor.service; disabled; vendor preset: disabled)
     Active: inactive (dead)
[root@testvm1 system]# systemctl start myMonitor.service
[root@testvm1 system]#


Por que nada está sendo enviado para o console? Isso ocorre porque, por padrão, a saída padrão ( stdout) de programas iniciados por systemd usando arquivos de unidade de serviço é redirecionada para o log do systemd. Por isso, pelo menos enquanto existirem os registros correspondentes, esses registros podem ser analisados. Vamos dar uma olhada no log e procurar entradas relacionadas ao nosso serviço e ao dia em que testamos. O comando correspondente será semelhante a este : journalctl -S today -u myMonitor.service. A chave -Sé uma versão abreviada --since. Ele permite que você especifique o período de tempo para o qual o utilitáriojournalctlprocurando registros. A questão não é que não estejamos interessados ​​em resultados anteriores. Em nosso caso, esses resultados simplesmente não serão. Essa chave é usada para reduzir o tempo que o utilitário precisa para pesquisar dados. Se o computador estiver funcionando por muito tempo, muitas entradas podem se acumular no log.



[root@testvm1 system]# journalctl -S today -u myMonitor.service
-- Logs begin at Mon 2020-06-08 07:47:20 EDT, end at Thu 2020-06-11 09:40:47 EDT. --
Jun 11 09:12:09 testvm1.both.org systemd[1]: Starting Logs system statistics to the systemd journal...
Jun 11 09:12:09 testvm1.both.org free[377966]:               total        used        free      shared  buff/cache   available
Jun 11 09:12:09 testvm1.both.org free[377966]: Mem:       12635740      522868    11032860        8016     1080012    11821508
Jun 11 09:12:09 testvm1.both.org free[377966]: Swap:       8388604           0     8388604
Jun 11 09:12:09 testvm1.both.org systemd[1]: myMonitor.service: Succeeded.
[root@testvm1 system]#


Uma tarefa que é iniciada usando um arquivo de configuração de serviço pode ser representada como um único programa, uma sequência de programas ou um script escrito em qualquer linguagem de script. Vamos adicionar myMonitor.serviceoutra tarefa ao arquivo de unidade , incluindo o [Service]seguinte no final da seção :



ExecStart=/usr/bin/lsblk


Vamos iniciar o serviço novamente e verificar o log. Deve haver algo lá que se pareça com o que é mostrado abaixo. Ou seja, o log deve conter a saída de dados por ambos os comandos:



Jun 11 15:42:18 testvm1.both.org systemd[1]: Starting Logs system statistics to the systemd journal...
Jun 11 15:42:18 testvm1.both.org free[379961]:               total        used        free      shared  buff/cache   available
Jun 11 15:42:18 testvm1.both.org free[379961]: Mem:       12635740      531788    11019540        8024     1084412    11812272
Jun 11 15:42:18 testvm1.both.org free[379961]: Swap:       8388604           0     8388604
Jun 11 15:42:18 testvm1.both.org lsblk[379962]: NAME          MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
Jun 11 15:42:18 testvm1.both.org lsblk[379962]: sda             8:0    0  120G  0 disk
Jun 11 15:42:18 testvm1.both.org lsblk[379962]: ├─sda1          8:1    0    4G  0 part /boot
Jun 11 15:42:18 testvm1.both.org lsblk[379962]: └─sda2          8:2    0  116G  0 part
Jun 11 15:42:18 testvm1.both.org lsblk[379962]:   ├─VG01-root 253:0    0    5G  0 lvm  /
Jun 11 15:42:18 testvm1.both.org lsblk[379962]:   ├─VG01-swap 253:1    0    8G  0 lvm  [SWAP]
Jun 11 15:42:18 testvm1.both.org lsblk[379962]:   ├─VG01-usr  253:2    0   30G  0 lvm  /usr
Jun 11 15:42:18 testvm1.both.org lsblk[379962]:   ├─VG01-tmp  253:3    0   10G  0 lvm  /tmp
Jun 11 15:42:18 testvm1.both.org lsblk[379962]:   ├─VG01-var  253:4    0   20G  0 lvm  /var
Jun 11 15:42:18 testvm1.both.org lsblk[379962]:   └─VG01-home 253:5    0   10G  0 lvm  /home
Jun 11 15:42:18 testvm1.both.org lsblk[379962]: sr0            11:0    1 1024M  0 rom
Jun 11 15:42:18 testvm1.both.org systemd[1]: myMonitor.service: Succeeded.
Jun 11 15:42:18 testvm1.both.org systemd[1]: Finished Logs system statistics to the systemd journal.


Agora, depois de termos certeza de que tudo está funcionando corretamente, criaremos, na pasta /etc/systemd/system, um arquivo de unidade de cronômetro, dando-lhe um nome myMonitor.timer. Adicione o seguinte ao arquivo:



# This timer unit is for testing
# By David Both
# Licensed under GPL V2
#

[Unit]
Description=Logs some system statistics to the systemd journal
Requires=myMonitor.service

[Timer]
Unit=myMonitor.service
OnCalendar=*-*-* *:*:00

[Install]
WantedBy=timers.target


O registro de data e hora OnCalendarneste arquivo ,, *-*-* *:*:00deve fazer com que o cronômetro chame a unidade a myMonitor.servicecada minuto. OnCalendarFalaremos mais sobre isso a seguir.



Enquanto isso, podemos dar uma olhada nas entradas de registro relacionadas ao início do serviço de timer. Também podemos ativar o modo de relógio com cronômetro. No entanto, monitorar o serviço permitirá que você veja os resultados quase em tempo real. Para fazer isso, você precisa executar journalctlcom a tecla -f( follow):



[root@testvm1 system]# journalctl -S today -f -u myMonitor.service
-- Logs begin at Mon 2020-06-08 07:47:20 EDT. --


Inicie o cronômetro, mas não o inclua na inicialização automática na inicialização do sistema. 



[root@testvm1 ~]# systemctl start myMonitor.timer
[root@testvm1 ~]#


Observe o que acontece por um tempo.



Um dos resultados aparece imediatamente. E os próximos serão exibidos em intervalos de cerca de um minuto. Observe a revista por alguns minutos.



[root@testvm1 system]# journalctl -S today -f -u myMonitor.service
-- Logs begin at Mon 2020-06-08 07:47:20 EDT. --
Jun 13 08:39:18 testvm1.both.org systemd[1]: Starting Logs system statistics to the systemd journal...
Jun 13 08:39:18 testvm1.both.org systemd[1]: myMonitor.service: Succeeded.
Jun 13 08:39:19 testvm1.both.org free[630566]:               total        used        free      shared  buff/cache   available
Jun 13 08:39:19 testvm1.both.org free[630566]: Mem:       12635740      556604    10965516        8036     1113620    11785628
Jun 13 08:39:19 testvm1.both.org free[630566]: Swap:       8388604           0     8388604
Jun 13 08:39:18 testvm1.both.org systemd[1]: Finished Logs system statistics to the systemd journal.
Jun 13 08:39:19 testvm1.both.org lsblk[630567]: NAME          MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
Jun 13 08:39:19 testvm1.both.org lsblk[630567]: sda             8:0    0  120G  0 disk
Jun 13 08:39:19 testvm1.both.org lsblk[630567]: ├─sda1          8:1    0    4G  0 part /boot
Jun 13 08:39:19 testvm1.both.org lsblk[630567]: └─sda2          8:2    0  116G  0 part
Jun 13 08:39:19 testvm1.both.org lsblk[630567]:   ├─VG01-root 253:0    0    5G  0 lvm  /
Jun 13 08:39:19 testvm1.both.org lsblk[630567]:   ├─VG01-swap 253:1    0    8G  0 lvm  [SWAP]
Jun 13 08:39:19 testvm1.both.org lsblk[630567]:   ├─VG01-usr  253:2    0   30G  0 lvm  /usr
Jun 13 08:39:19 testvm1.both.org lsblk[630567]:   ├─VG01-tmp  253:3    0   10G  0 lvm  /tmp
Jun 13 08:39:19 testvm1.both.org lsblk[630567]:   ├─VG01-var  253:4    0   20G  0 lvm  /var
Jun 13 08:39:19 testvm1.both.org lsblk[630567]:   └─VG01-home 253:5    0   10G  0 lvm  /home
Jun 13 08:39:19 testvm1.both.org lsblk[630567]: sr0            11:0    1 1024M  0 rom
Jun 13 08:40:46 testvm1.both.org systemd[1]: Starting Logs system statistics to the systemd journal...
Jun 13 08:40:46 testvm1.both.org free[630572]:               total        used        free      shared  buff/cache   available
Jun 13 08:40:46 testvm1.both.org free[630572]: Mem:       12635740      555228    10966836        8036     1113676    11786996
Jun 13 08:40:46 testvm1.both.org free[630572]: Swap:       8388604           0     8388604
Jun 13 08:40:46 testvm1.both.org lsblk[630574]: NAME          MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
Jun 13 08:40:46 testvm1.both.org lsblk[630574]: sda             8:0    0  120G  0 disk
Jun 13 08:40:46 testvm1.both.org lsblk[630574]: ├─sda1          8:1    0    4G  0 part /boot
Jun 13 08:40:46 testvm1.both.org lsblk[630574]: └─sda2          8:2    0  116G  0 part
Jun 13 08:40:46 testvm1.both.org lsblk[630574]:   ├─VG01-root 253:0    0    5G  0 lvm  /
Jun 13 08:40:46 testvm1.both.org lsblk[630574]:   ├─VG01-swap 253:1    0    8G  0 lvm  [SWAP]
Jun 13 08:40:46 testvm1.both.org lsblk[630574]:   ├─VG01-usr  253:2    0   30G  0 lvm  /usr
Jun 13 08:40:46 testvm1.both.org lsblk[630574]:   ├─VG01-tmp  253:3    0   10G  0 lvm  /tmp
Jun 13 08:40:46 testvm1.both.org lsblk[630574]:   ├─VG01-var  253:4    0   20G  0 lvm  /var
Jun 13 08:40:46 testvm1.both.org lsblk[630574]:   └─VG01-home 253:5    0   10G  0 lvm  /home
Jun 13 08:40:46 testvm1.both.org lsblk[630574]: sr0            11:0    1 1024M  0 rom
Jun 13 08:40:46 testvm1.both.org systemd[1]: myMonitor.service: Succeeded.
Jun 13 08:40:46 testvm1.both.org systemd[1]: Finished Logs system statistics to the systemd journal.
Jun 13 08:41:46 testvm1.both.org systemd[1]: Starting Logs system statistics to the systemd journal...
Jun 13 08:41:46 testvm1.both.org free[630580]:               total        used        free      shared  buff/cache   available
Jun 13 08:41:46 testvm1.both.org free[630580]: Mem:       12635740      553488    10968564        8036     1113688    11788744
Jun 13 08:41:46 testvm1.both.org free[630580]: Swap:       8388604           0     8388604
Jun 13 08:41:47 testvm1.both.org lsblk[630581]: NAME          MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
Jun 13 08:41:47 testvm1.both.org lsblk[630581]: sda             8:0    0  120G  0 disk
Jun 13 08:41:47 testvm1.both.org lsblk[630581]: ├─sda1          8:1    0    4G  0 part /boot
Jun 13 08:41:47 testvm1.both.org lsblk[630581]: └─sda2          8:2    0  116G  0 part
Jun 13 08:41:47 testvm1.both.org lsblk[630581]:   ├─VG01-root 253:0    0    5G  0 lvm  /
Jun 13 08:41:47 testvm1.both.org lsblk[630581]:   ├─VG01-swap 253:1    0    8G  0 lvm  [SWAP]
Jun 13 08:41:47 testvm1.both.org lsblk[630581]:   ├─VG01-usr  253:2    0   30G  0 lvm  /usr
Jun 13 08:41:47 testvm1.both.org lsblk[630581]:   ├─VG01-tmp  253:3    0   10G  0 lvm  /tmp
Jun 13 08:41:47 testvm1.both.org lsblk[630581]:   ├─VG01-var  253:4    0   20G  0 lvm  /var
Jun 13 08:41:47 testvm1.both.org lsblk[630581]:   └─VG01-home 253:5    0   10G  0 lvm  /home
Jun 13 08:41:47 testvm1.both.org lsblk[630581]: sr0            11:0    1 1024M  0 rom
Jun 13 08:41:47 testvm1.both.org systemd[1]: myMonitor.service: Succeeded.
Jun 13 08:41:47 testvm1.both.org systemd[1]: Finished Logs system statistics to the systemd journal.


Certifique-se de verificar o status do cronômetro e o status do serviço.



Você conseguiu perceber aqui o que eu percebi? Você deve ter notado pelo menos duas coisas ao ler a revista.



Em primeiro lugar - o fato de que você não precisa fazer algo especial para o registo que ExecStartde myMonitor.serviceescrever em stdout. Este recurso faz parte das funções de inicialização padrão do systemd. Mas isso significa que você provavelmente precisará ter cuidado ao executar scripts de arquivos de configuração de serviço, observando em quantos dados eles gravam stdout.



Em segundo lugar, você deve ter notado que o cronômetro não começa exatamente em:00segundos de cada minuto, e nem mesmo exatamente um minuto após a última execução. Esta é uma das características de tais temporizadores, se for necessário (ou se ferir os sentimentos do administrador do sistema), este comportamento dos temporizadores pode ser alterado tornando-os mais precisos.



O motivo pelo qual o cronômetro não inicia em :00segundos de cada minuto é porque o sistema tende a evitar que vários serviços sejam iniciados simultaneamente. Por exemplo, ao configurar o indicador de tempo, OnCalendarvocê pode usar valores como Weekly, Dailye outros. Essas formas abreviadas de nomear pontos no tempo são configuradas de modo que os cronômetros em que são usados ​​comecem em00:00:00o dia correspondente. Quando vários temporizadores são configurados dessa forma, são grandes as chances de que todos eles disparem ao mesmo tempo.



É por isso que os temporizadores do systemd são deliberadamente projetados de modo que não iniciem exatamente no horário especificado, mas com algum desvio aleatório dele. Este desvio não pode ser considerado totalmente acidental. Os cronômetros começam em algum lugar em uma janela de tempo que começa no momento especificado e termina a um minuto do original. Este tempo, de acordo com a documentação do systemd.timer, é mantido em estado estável, levando em consideração todos os outros temporizadores declarados no sistema. No fragmento de registro acima, você pode ver que o cronômetro é acionado imediatamente após ser iniciado e, em seguida, aproximadamente 46 ou 47 segundos após o início de cada minuto seguinte.



Na maioria das vezes, essa abordagem probabilística para determinar o tempo exato dos temporizadores é adequada para todos. Ao programar tarefas, como fazer uma cópia de backup de algo enquanto essas tarefas são realizadas fora do horário comercial, isso não causa problemas. O administrador do sistema, configurando tarefas cron, pode especificar horários claramente definidos para iniciá-los, algo como 01:05:00tentar garantir que essas tarefas não entrem em conflito com outras. Existe uma ampla gama de maneiras de especificar o tempo que permite isso. Mudanças aleatórias na hora de início de uma tarefa que não excedem um minuto geralmente não desempenham um papel especial.



Mas, para algumas tarefas, o tempo exato do cronômetro é extremamente importante. Nesses casos, ao definir os temporizadores, você pode especificar um tempo mais preciso de sua operação (até a precisão, medida em microssegundos). Isso é feito adicionando-se ao arquivo de descrição do cronômetro, na seção Timer, uma construção semelhante à seguinte:



AccuracySec=1us


Você pode usar palavras-chave especiais para especificar a precisão desejada do cronômetro. Essas palavras-chave também podem ser usadas ao configurar eventos recorrentes e únicos. O sistema entende as seguintes palavras-chave:



  • Microssegundo: usec, us, µs.
  • Milissegundo: msec, ms.
  • Segundo: seconds, second, sec, s.
  • Minuto: minutes, minute, min, m.
  • Hora: hours, hour, hr, h.
  • Dia: days, day, d.
  • Semana: weeks, week, w.
  • Mês: months, month, M(o mês é definido como 30,44 dias).
  • Ano: years, year, y(o ano é definido como 365,25 dias).


Todos os temporizadores padrão disponíveis /usr/lib/systemd/systemsão configurados em intervalos muito mais longos que definem a precisão de seu acionamento, pois, no caso desses temporizadores, o acionamento em um horário estritamente especificado não é particularmente importante. Dê uma olhada nas especificações de alguns dos temporizadores gerados pelo sistema:



[root@testvm1 system]# grep Accur /usr/lib/systemd/system/*timer
/usr/lib/systemd/system/fstrim.timer:AccuracySec=1h
/usr/lib/systemd/system/logrotate.timer:AccuracySec=1h
/usr/lib/systemd/system/logwatch.timer:AccuracySec=12h
/usr/lib/systemd/system/mlocate-updatedb.timer:AccuracySec=24h
/usr/lib/systemd/system/raid-check.timer:AccuracySec=24h
/usr/lib/systemd/system/unbound-anchor.timer:AccuracySec=24h
[root@testvm1 system]#


Para obter uma melhor compreensão da estrutura interna dos arquivos de temporizador do diretório /usr/lib/systemd/system, você pode visualizar seu conteúdo.



Você não precisa configurar nosso cronômetro de aprendizado para ser ativado quando o sistema inicializar. No entanto, se desejar, você pode usar o seguinte comando para isso:



[root@testvm1 system]# systemctl enable myMonitor.timer


Os arquivos de cronômetro que você criar não precisam ser executáveis. Além disso, os arquivos de configuração de serviço não precisam ser configurados para serem ativados na inicialização, pois são chamados por temporizadores. Se necessário, o serviço também pode ser chamado manualmente a partir da linha de comando. Tente fazer isso e verifique o log do systemd.



Para saber mais sobre a precisão dos temporizadores, como especificar a hora de disparo do evento e como disparar eventos, consulte a documentação para systemd.timere systemd.time.



Tipos de cronômetro



Os cronômetros do Systemd têm outros recursos que os cron jobs não possuem, únicos ou repetitivos, que são chamados apenas com datas em tempo real e em tempo real. Os cronômetros do Systemd podem ser configurados para serem chamados com base nas mudanças no estado de outras unidades do systemd. Por exemplo, um cronômetro pode ser configurado para ser acionado após um determinado tempo após a inicialização do sistema, após o usuário efetuar login nele ou após um determinado tempo após a ativação de um determinado serviço. Esses temporizadores são chamados de monotônicos. Esses temporizadores são redefinidos após cada reinicialização do sistema.



A tabela a seguir mostra uma lista de temporizadores monotônicos com uma breve descrição de cada um deles. Também há uma descrição do cronômetro.OnCalendar, que não é monótono e é usado nos casos em que você precisa organizar um lançamento único ou repetido de algo no futuro. Esta tabela é baseada na documentação systemd.timer.

Cronômetro Monotone Descrição
OnActiveSec=


X O tempo de operação do temporizador é definido em relação ao momento da ativação do temporizador.
OnBootSec=


X O cronômetro é definido em relação ao momento em que o sistema é inicializado.
OnStartupSec=


X . OnBootSec=, . , , , , , .
OnUnitActiveSec=


X , , , .
OnUnitInactiveSec=


X , , , .
OnCalendar=


  . systemd.time(7). OnActiveSec=. — systemd, , cron.


Ao configurar temporizadores monotônicos, as mesmas palavras-chave podem ser usadas conforme descrito acima ao falar sobre AccuracySec. Mas deve-se observar que o systemd converte os intervalos de tempo correspondentes em segundos. Por exemplo, você pode definir um cronômetro que dispara uma vez, cinco dias após a inicialização do sistema. Pode parecer uma descrição como esta: OnBootSec=5d. Se o computador foi inicializado 2020-06-15às 09:45:27, o cronômetro iniciará 2020-06-20às 09:45:27(ou dentro de 1 minuto após esse momento).



Descrição dos eventos da agenda



A aplicação de eventos de calendário é uma parte fundamental da descrição de cronômetros que são chamados em intervalos regulares. Vamos examinar alguns dos recursos de tais eventos usados ​​ao definir o indicador de tempo OnCalendar.



O Systemd e seus temporizadores correspondentes usam um formato de hora e data diferente do crontab. Este formato é mais flexível do que o usado no crontab. Ele permite que você especifique a data e a hora de uma forma simplificada, no estilo de comando at. Para aqueles familiarizados com ele at, deve ser fácil entender as configurações do cronômetro do systemd.



Quando usado OnCalendar=para configurar temporizadores, o seguinte formato básico é usado para especificar a data e hora:



DOW YYYY-MM-DD HH:MM:SS


DOW(Dia da semana) é uma parte opcional da construção acima. Em outros campos, você pode usar o símbolo de asterisco ( *) para representar qualquer valor que possa estar na posição que ocupa. Todas as formas de indicação de data e hora são convertidas para a forma normalizada. Se nenhuma hora for especificada, presume-se que sim 00:00:00. Se a data não for especificada, mas a hora for especificada, o cronômetro funcionará no dia em que começar (relativamente falando, "hoje") ou no dia seguinte ("amanhã"). Depende da hora atual. Meses e dias da semana podem ser nomeados usando seus nomes. Você pode usar listas de valores separados por vírgulas aqui. Os intervalos de valores podem ser separados por três pontos ( ), que aparecem entre o valor inicial e final do intervalo.



Ao especificar datas, temos algumas opções interessantes à nossa disposição. Assim, um til (~) pode ser usado para indicar o último dia de um mês, ou para indicar uma data um determinado número de dias antes do último dia do mês. A barra (/) pode ser usada como um modificador para indicar o dia da semana.



A tabela a seguir mostra alguns exemplos típicos de tempo usado em uma expressão OnCalendar.



Exemplo de apresentação de um evento da agenda DOW YYYY-MM-DD HH:MM:SS

Descrição
*-*-* 00:15:30


Todos os dias de cada mês de cada ano, 15 minutos e 30 segundos depois da meia-noite.
Weekly


Toda segunda-feira às 00:00:00.
Mon *-*-* 00:00:00


O mesmo que Weekly.
Mon


O mesmo que Weekly.
Wed 2020-*-*


Toda quarta-feira de 2020 às 00:00:00.
Mon..Fri 2021-*-*


Todos os dias da semana em 2021 às 00:00:00.
2022-6,7,8-1,15 01:15:00


1 e 15 de junho, julho e agosto de 2022 01:15:00após a meia-noite.
Mon *-05~03


, , , 3 .
Mon..Fri *-08~04


, 4 , .
*-05~03/2


3 , , — , . . , ~.
*-05-03/2


, — . . , (-).


,



O Systemd tem uma ótima ferramenta para verificar e examinar as especificações de eventos do calendário. Estamos falando de uma equipe systemd-analyze calendarque analisa as descrições dos eventos do calendário e os apresenta de forma normalizada. Este comando também fornece outras informações interessantes, como a data e hora do próximo evento, e o tempo aproximado restante até aquele momento.



Primeiro, vamos dar uma olhada na especificação, que contém apenas a data, não contém informações sobre o tempo (note que os tempos nos campos Next elapsee (in UTC)são diferentes, esta diferença depende do fuso horário local):



[student@studentvm1 ~]$ systemd-analyze calendar 2030-06-17
  Original form: 2030-06-17                
Normalized form: 2030-06-17 00:00:00        
    Next elapse: Mon 2030-06-17 00:00:00 EDT
       (in UTC): Mon 2030-06-17 04:00:00 UTC
       From now: 10 years 0 months left    
[root@testvm1 system]#


Agora vamos adicionar informações de tempo à descrição. Neste exemplo, a data e a hora são analisadas separadamente, como entidades que não estão relacionadas entre si:



[root@testvm1 system]# systemd-analyze calendar 2030-06-17 15:21:16
  Original form: 2030-06-17                
Normalized form: 2030-06-17 00:00:00        
    Next elapse: Mon 2030-06-17 00:00:00 EDT
       (in UTC): Mon 2030-06-17 04:00:00 UTC
       From now: 10 years 0 months left    

  Original form: 15:21:16                  
Normalized form: *-*-* 15:21:16            
    Next elapse: Mon 2020-06-15 15:21:16 EDT
       (in UTC): Mon 2020-06-15 19:21:16 UTC
       From now: 3h 55min left              
[root@testvm1 system]#


Agora considere um exemplo em que data e hora são consideradas juntas. Para fazer isso, eles devem ser colocados entre aspas. Mas se você usar tal construção em OnCalendar, não se esqueça de remover as aspas, caso contrário, você encontrará erros:



[root@testvm1 system]# systemd-analyze calendar "2030-06-17 15:21:16"
Normalized form: 2030-06-17 15:21:16        
    Next elapse: Mon 2030-06-17 15:21:16 EDT
       (in UTC): Mon 2030-06-17 19:21:16 UTC
       From now: 10 years 0 months left    
[root@testvm1 system]#


Agora vamos verificar algo da tabela anterior. Gosto especialmente desta descrição dela:



2022-6,7,8-1,15 01:15:00


Vamos analisar:



[root@testvm1 system]# systemd-analyze calendar "2022-6,7,8-1,15 01:15:00"
  Original form: 2022-6,7,8-1,15 01:15:00
Normalized form: 2022-06,07,08-01,15 01:15:00
    Next elapse: Wed 2022-06-01 01:15:00 EDT
       (in UTC): Wed 2022-06-01 05:15:00 UTC
       From now: 1 years 11 months left
[root@testvm1 system]#


Agora vamos dar uma olhada na descrição Mon *-05~3, mas desta vez pediremos ao programa informações sobre os próximos 5 tempos do cronômetro, que usa as seguintes configurações:



[root@testvm1 ~]# systemd-analyze calendar --iterations=5 "Mon *-05~3"
  Original form: Mon *-05~3                
Normalized form: Mon *-05~03 00:00:00      
    Next elapse: Mon 2023-05-29 00:00:00 EDT
       (in UTC): Mon 2023-05-29 04:00:00 UTC
       From now: 2 years 11 months left    
       Iter. #2: Mon 2028-05-29 00:00:00 EDT
       (in UTC): Mon 2028-05-29 04:00:00 UTC
       From now: 7 years 11 months left    
       Iter. #3: Mon 2034-05-29 00:00:00 EDT
       (in UTC): Mon 2034-05-29 04:00:00 UTC
       From now: 13 years 11 months left    
       Iter. #4: Mon 2045-05-29 00:00:00 EDT
       (in UTC): Mon 2045-05-29 04:00:00 UTC
       From now: 24 years 11 months left    
       Iter. #5: Mon 2051-05-29 00:00:00 EDT
       (in UTC): Mon 2051-05-29 04:00:00 UTC
       From now: 30 years 11 months left    
[root@testvm1 ~]#


Acredito que cobrimos casos de uso suficientes systemd-analyze calendarpara você começar a testar suas próprias descrições de eventos de agenda. Lembre-se de que a ferramenta systemd-analyzepossui outros recursos interessantes.



Materiais adicionais



Existem muitas publicações sobre o systemd na Internet, mas a maioria delas são muito curtas, muito simplistas ou até mesmo com bugs. Este artigo fornece algumas boas fontes de informações sobre o systemd. Abaixo está uma lista de links para mais alguns materiais de qualidade neste tópico. 



  • Um guia prático para o systemd pelo Projeto Fedora.
  • Uma folha de dicas do Projeto Fedora que mapeia os comandos SystemV e systemd legados.
  • Detalhes sobre o systemd e por que ele foi criado.
  • Material com informação e aconselhamento, dedicado ao systemd.
  • (Lennart Poettering), systemd. , 2010 2011, . systemd .
  • systemd.
  • systemd.




Os cronômetros do Systemd podem ser usados ​​para realizar as mesmas tarefas que os cron jobs fazem. Mas o systemd oferece mais flexibilidade em termos de configuração de calendário e cronômetros monotônicos.



Mesmo que os arquivos de configuração de serviço que criamos durante nossos experimentos sejam geralmente chamados usando temporizadores, você pode chamá-los a qualquer momento usando um comando como systemctl start myMonitor.service. Um cronômetro pode iniciar várias tarefas. Isso pode ser, por exemplo, scripts Bash e utilitários Linux. Um arquivo de configuração de serviço pode ser composto de forma que, ao ser chamado, vários scripts sejam executados. Você também pode fazer os scripts rodarem separadamente.



Se falarmos sobre a coexistência de systemd, cron e at, então gostaria de observar que ainda não vi nenhum sinal de que cron ou at estaria obsoleto. Espero que eles continuem a ter suporte, pois pelo menos é muito mais fácil do que o systemd usar para agendar tarefas únicas.



O que você está usando? Timers Systemd ou trabalhos cron?






All Articles