Trabalhando com Timers em Systemd

Explica como as unidades do temporizador systemd programam o trabalho e como configurar temporizadores em tempo real, monotônicos e transitórios.

Os arquivos de unidade de temporizador são um tipo de arquivo systemd que o utilitário systemctl usa para programar tarefas, semelhante ao utilitário cron que usa crontab e outros jobs cron para a mesma finalidade.

Observe que o daemon cron é executado como um serviço dentro do systemd, portanto, as unidades de temporizador são preferidas porque removem uma camada de processamento adicionado e oferecem muito mais utilidade e configuração mais granular do que está disponível no serviço cron.

Geralmente, os pacotes que usam serviços específicos para funcionar no sistema incluem seus próprios arquivos de unidade do temporizador systemd. Assim, quando esses pacotes são instalados com o Oracle Linux, os arquivos de unidade do temporizador são incluídos automaticamente. É possível exibir os arquivos de temporizador no sistema com o seguinte comando:

systemctl list-unit-files --type=timer
Observação

A lista de arquivos do timer pode ser diferente dependendo de onde o Oracle Linux está sendo executado, como em uma instância do Oracle Cloud Infrastructure, em um sistema físico etc.

Cada arquivo de unidade de temporizador contém configurações de parâmetro que gerenciam a programação de uma tarefa. Por exemplo, a programação para execução de dnf-makecache.service é definida no arquivo dnf-makecache.timer. O arquivo contém as seguintes configurações:

systemctl cat dnf-makecache.timer
# /usr/lib/systemd/system/dnf-makecache.timer
[Unit]
Description=dnf makecache --timer
ConditionKernelCommandLine=!rd.live.image
# See comment in dnf-makecache.service
ConditionPathExists=!/run/ostree-booted
Wants=network-online.target

[Timer]
OnBootSec=10min
OnUnitInactiveSec=1h
RandomizedDelaySec=60m
Unit=dnf-makecache.service

[Install]
WantedBy=timers.target

As informações de programação são especificadas na seção [Timer].

Na configuração de amostra, o serviço dnf-makecache.service é definido para ser executado automaticamente 10 minutos após a inicialização do sistema. O serviço então entra no modo ocioso por uma hora, conforme especificado pelo parâmetro OnUnitInactiveSec. No final da hora, o serviço é executado novamente. Este ciclo continua a cada hora indefinidamente.

A definição RandomizedDelaySec fornece um limite de valor para o quanto uma execução pode ser atrasada além de sua programação.

No exemplo, o serviço pode ser executado um minuto depois de sua programação, no máximo. Esse parâmetro é útil para impedir que muitos jobs comecem ao mesmo tempo em uma programação especificada, o que, caso contrário, arriscaria sobrecarregar os recursos.

OnCalendar é outro parâmetro útil para programação de tarefas. Suponha que o parâmetro esteja definido da seguinte forma:

OnCalendar=*:00/10

O *:00 indica a cada hora na parte superior da hora, enquanto a definição /10 indica 10 minutos. Portanto, o job é definido para ser executado por hora, em dez minutos após o início da hora.

Para obter uma lista completa dos parâmetros do arquivo de unidade do temporizador systemd para programar um job, consulte as páginas manuais do systemd.timer(5).

Dica

Para obter um tutorial sobre como usar o systemd no Oracle Linux, incluindo como configurar arquivos de unidade do temporizador systemd, consulte https://docs.oracle.com/en/learn/ol-systemd/.

Usando Unidades de Temporizador para Controlar o Tempo de Execução da Unidade de Serviço

Explica como as unidades de temporizador substituem tarefas cron e como inspecionar, ativar e monitorar serviços acionados por temporizador.

É possível configurar unidades de temporizador para controlar quando as unidades de serviço são executadas.

Você pode usar unidades de temporizador em vez de configurar o daemon cron para eventos baseados em tempo. Unidades de temporizador podem ser mais complicadas de configurar do que criar uma entrada crontab. No entanto, as unidades de temporizador são mais configuráveis e os serviços que elas controlam podem ser configurados para melhor registro e integração mais profunda com a arquitetura systemd.

As unidades do temporizador são iniciadas, ativadas e interrompidas da mesma forma que as unidades de serviço. Por exemplo, para ativar e iniciar uma unidade de temporizador imediatamente, digite:

sudo systemctl enable --now myscript.timer

Para listar todos os temporizadores existentes no sistema, para ver quando eles foram executados pela última vez e quando eles foram configurados para execução, digite:

systemctl list-timers

Para obter mais informações sobre os temporizadores do sistema, consulte as páginas manuais systemd.timer(5) e systemd.time(7).

Configurando uma Unidade de Temporizador em Tempo Real

Temporizadores em tempo real são ativados em um evento de calendário, semelhante aos eventos em um crontab. A opção OnCalendar especifica quando o temporizador executa um serviço.

  • Se necessário, crie um arquivo .service que defina o serviço a ser acionado pela unidade do timer. No procedimento a seguir, o serviço de amostra é /etc/systemd/system/update.service, que é uma unidade de serviço que executa um script de atualização.

    Para obter mais informações sobre como criar unidades de serviço, consulte Criando um serviço systemd baseado em usuário.

  • Decida a hora e a frequência de execução do serviço. Neste procedimento, o temporizador é configurado para executar o serviço a cada 2 horas, de segunda a sexta-feira.

Esta tarefa mostra como criar um temporizador do sistema para acionar um serviço a ser executado com base em um evento de calendário. A definição do evento de calendário é semelhante às entradas que você coloca em uma tarefa cron.

  1. Crie o /etc/systemd/system/update.timer com o seguinte conteúdo:
    [Unit]
    Description="Run the update.service every two hours from Mon to Fri."
    
    [Timer]
    OnCalendar=Mon..Fri 00/2 
    Unit=update.service
    
    [Install]
    WantedBy=multi-user.target

    OnCalendar pode usar uma definição direta, como OnCalendar=weekly, ou pode usar definições mais complexas, que são mais detalhadas. No entanto, o formato para definir configurações é constante, da seguinte forma:

    DayofWeek Year-Month-Day Hour:Minute:Second

    A seguinte definição significa "os primeiros 4 dias de cada mês às 12:00 do meio-dia, mas somente se esse dia for uma segunda ou uma terça-feira":

    OnCalendar=Mon,Tue *-*-01..04 12:00:00

    Para obter outras maneiras de definir OnCalendar e para obter mais opções de temporizador que você pode configurar no arquivo de temporizador do sistema, consulte as páginas manuais systemd.timer(5) e systemd.time(7).

  2. Verifique se todos os arquivos relacionados a este temporizador estão configurados corretamente.
    systemd-analyze verify /etc/systemd/system/update.*

    Todos os erros detectados são reportados na tela.

  3. Inicie o temporizador.
    sudo systemctl start update.timer

    Este comando inicia o temporizador somente para a sessão atual.

  4. Certifique-se de que o temporizador seja iniciado quando o sistema for inicializado.
    sudo systemctl enable update.timer

Configurando uma unidade de temporizador monotônico

Temporizadores monotônicos são ativados após um intervalo de tempo relativo a um ponto inicial variável, como um evento de inicialização, ou quando uma unidade systemd específica se torna ativa. Essas unidades de temporizador param se o computador estiver temporariamente suspenso ou desligado. Os temporizadores monotônicos são configurados usando a opção OnTypeSec, em que Type é o nome do evento ao qual o temporizador está relacionado. Os temporizadores monotônicos comuns incluem OnBootSec e OnUnitActiveSec.

  • Se necessário, crie um arquivo .service que defina o serviço a ser acionado pela unidade do timer. No procedimento a seguir, o serviço de amostra é /etc/systemd/system/update.service, que é uma unidade de serviço que executa um script de atualização.

    Para obter mais informações sobre como criar unidades de serviço, consulte Criando um serviço systemd baseado em usuário.

  • Decida a hora e a frequência de execução do serviço. Neste procedimento, o temporizador é configurado para executar o serviço 10 minutos após a inicialização do sistema e a cada 2 horas a partir da última ativação do serviço.

Esta tarefa mostra como criar um temporizador do sistema para acionar um serviço a ser executado em eventos específicos, que são quando o sistema é inicializado ou após 2 horas decorridas a partir da ativação do temporizador.

  1. Crie o /etc/systemd/system/update.timer com o seguinte conteúdo:
    [Unit]
    Description="Run the update.service every two hours from Mon to Fri."
    
    [Timer]
    OnBootSec=10min
    OnUnitActiveSec=2h
    Unit=update.service
    
    [Install]
    WantedBy=multi-user.target

    Para obter mais opções de temporizador que você pode configurar no temporizador do sistema, consulte as páginas manuais systemd.timer(5) e systemd.time(7).

  2. Verifique se todos os arquivos relacionados a este temporizador estão configurados corretamente.
    systemd-analyze verify /etc/systemd/system/update.*

    Todos os erros detectados são reportados na tela.

  3. Inicie o temporizador.
    sudo systemctl start update.timer

    Este comando inicia o temporizador somente para a sessão atual.

  4. Certifique-se de que o temporizador seja iniciado quando o sistema for inicializado.
    sudo systemctl enable update.timer

Executando uma Unidade Temporizadora Transiente

Demonstra como iniciar temporizadores one-off com systemctl run para que você possa programar tarefas ad hoc sem criar arquivos de unidade.

Temporizadores transitórios são temporizadores temporários que são válidos apenas para a sessão atual.

Esses temporizadores podem ser criados para executar um programa ou script diretamente sem exigir que unidades de serviço ou temporizador sejam configuradas no systemd. Essas unidades são geradas com o comando systemd-run. Consulte a página do manual systemd-run(1) para obter mais informações.

As opções de parâmetro que você adicionaria ao arquivo unit-file.timer também servem como argumentos quando você usa o comando systemd-run para executar uma unidade de temporizador transitória.

Os exemplos a seguir mostram como usar o systemd-run para ativar temporizadores transitórios.

  • Execute update.service após 2 horas.

    sudo systemd-run --on-active="2h" --unit update.service
  • Crie ~/tmp/myfile após 1 hora.

    sudo systemd-run --on-active="1h" /bin/touch ~/tmp/myfile
  • Execute ~/myscripts/update.sh 5 minutos após o início do gerenciador de serviços. Use esta sintaxe para executar um serviço depois que o gerenciador de serviços for iniciado no log-in do usuário.

    sudo systemd-run --on-startup="5m" ~/myscripts/update.sh
  • Execute myjob.service 10 minutos após a inicialização do sistema.

    sudo systemd-run --on-boot="10m" --unit myjob.service
  • Execute report.service no final do dia.

    sudo systemd-run --on-calendar="17:00:00"