MCU & FPGA Infraestrutura,IoT,Sistemas Operacionais Criando serviços com systemd no Linux

Criando serviços com systemd no Linux


2. Criando o primeiro serviço: Unit, Service e Install

2.1 Uma aplicação de demonstração

Vamos criar um coletor Python que escreve mensagens a cada cinco segundos e atende a pedidos de encerramento.

sudo mkdir -p /opt/coletor
sudo useradd --system --home-dir /opt/coletor --shell /usr/sbin/nologin coletor

Se a conta coletor já existir, não repita o comando de criação. O caminho de nologin pode variar entre distribuições; verifique com command -v nologin.

Crie /opt/coletor/coletor.py:

#!/usr/bin/env python3
import logging
import signal
import time

executando = True

logging.basicConfig(
    level=logging.INFO,
    format="%(asctime)s %(levelname)s %(message)s",
)

def encerrar(signum, frame):
    global executando
    logging.info("Sinal %s recebido", signum)
    executando = False

signal.signal(signal.SIGTERM, encerrar)
signal.signal(signal.SIGINT, encerrar)

logging.info("Coletor iniciado")
while executando:
    logging.info("Leitura simulada de sensores")
    time.sleep(5)
logging.info("Coletor finalizado normalmente")

Aplique permissões:

sudo chown root:root /opt/coletor/coletor.py
sudo chmod 644 /opt/coletor/coletor.py
python3 /opt/coletor/coletor.py  # Ctrl+C para encerrar

Em produção, uma aplicação embarcada real poderia substituir a leitura simulada por aquisição UART, I²C, SPI, GPIO ou publicação MQTT, com as devidas permissões.

2.2 O arquivo /etc/systemd/system/coletor.service

[Unit]
Description=Serviço de coleta de sensores
Documentation=man:systemd.service(5)
After=network.target

[Service]
Type=exec
User=coletor
Group=coletor
WorkingDirectory=/opt/coletor
ExecStart=/usr/bin/python3 /opt/coletor/coletor.py
Restart=on-failure
RestartSec=5s

[Install]
WantedBy=multi-user.target

Confira o caminho do interpretador com command -v python3. Type=exec é recomendado aqui em versões de systemd que o suportam; ele permite detectar certas falhas da etapa de execução, mas não garante que a aplicação esteja operacionalmente pronta.

2.3 As diretivas de [Unit]

  • Description=: texto descritivo visível em systemctl status.
  • Documentation=: referência de manual ou URL.
  • After= e Before=: ordenação, não ativação automática de dependências.
  • Wants=: dependência fraca; tenta ativar a outra Unit.
  • Requires=: dependência mais forte; em conjunto com ordenação, falhas de inicialização podem impedir o serviço.
  • Conflicts=: unidades incompatíveis durante ativação.

Por exemplo:

[Unit]
Wants=network-online.target
After=network-online.target

network.target não garante internet; network-online.target expressa espera pela rede considerada configurada pelo gerenciador de rede, não conectividade comprovada com um broker MQTT remoto. A aplicação deve implementar tentativas de reconexão.

2.4 As diretivas de [Service]

Tipos de inicialização:

Type=Uso típico
simpleProcesso de longa duração sem protocolo explícito de prontidão
execComo simple, mas aguarda sucesso da etapa exec
oneshotTarefa finita, conclusão considerada na inicialização
forkingDaemon clássico que se desanexa em processo filho
notifyProcesso comunica prontidão via sd_notify
dbusProntidão vinculada a aquisição de nome no barramento

User= e Group= delimitam a identidade do processo, mas não concedem automaticamente acesso a dispositivos ou arquivos. WorkingDirectory= define o diretório de trabalho do processo. ExecStart= indica o programa e argumentos.

Não assuma que ExecStart= é uma linha de shell. Isto não é uma composição shell válida para systemd:

ExecStart=cd /opt/coletor && python3 coletor.py

Prefira:

WorkingDirectory=/opt/coletor
ExecStart=/usr/bin/python3 /opt/coletor/coletor.py

Se realmente necessário, invoque explicitamente um shell, como /bin/sh -c '...', com cuidado na expansão de caracteres.

ExecStartPre= pode verificar pré-condições; ExecStartPost= executa trabalho após a etapa de inicialização conforme o tipo; ExecStop= configura comando de parada opcional. No exemplo Python, ExecStop= é desnecessário: o programa já trata SIGTERM.

Restart=on-failure
RestartSec=5s

Em caso de falha reconhecida, o serviço poderá ser reiniciado após cinco segundos, sujeito aos limites de taxa de inicialização. Uma parada pedida com systemctl stop não aciona essa política.

2.5 Configurando ambiente

Variáveis simples podem ser definidas na Unit:

Environment=MQTT_HOST=192.168.1.50
Environment=MQTT_PORT=1883

Ou por arquivo:

EnvironmentFile=/etc/coletor/coletor.env

Exemplo de arquivo:

MQTT_HOST=192.168.1.50
MQTT_PORT=1883
LOG_LEVEL=INFO

No Python:

import os
host = os.getenv("MQTT_HOST", "localhost")
porta = int(os.getenv("MQTT_PORT", "1883"))

Não trate Environment= ou EnvironmentFile= como armazenamento seguro de segredos. Para credenciais sensíveis, considere LoadCredential= e políticas de acesso adequadas.

2.6 O papel de [Install]

[Install]
WantedBy=multi-user.target

Essa declaração é utilizada em operações como systemctl enable, normalmente produzindo links simbólicos que associam a Unit ao target. Não executa o programa por si só.

2.7 Validar, iniciar e acompanhar

sudo systemd-analyze verify /etc/systemd/system/coletor.service
sudo systemctl daemon-reload
sudo systemctl start coletor.service
systemctl status coletor.service
sudo journalctl -u coletor.service -f

Para obter os logs do boot atual:

sudo journalctl -b -u coletor.service

Para habilitar no boot:

sudo systemctl enable --now coletor.service
systemctl is-enabled coletor.service

Experimento de supervisão

Obtenha o PID principal:

systemctl show -p MainPID --value coletor.service

Somente no ambiente de testes, simule a falha substituindo PID_OBTIDO pelo valor retornado:

sudo kill -KILL PID_OBTIDO
sudo journalctl -u coletor.service -f

Observe a tentativa de reinício. Compare depois com a parada intencional:

sudo systemctl stop coletor.service

Ponto de aprendizagem

O código implementa a lógica do coletor; a Unit especifica política de execução e supervisão. Essa separação simplifica manutenção, testes e operação.


0 0 votos
Classificação do artigo
Inscrever-se
Notificar de
guest
0 Comentários
mais antigos
mais recentes Mais votado
Feedbacks embutidos
Ver todos os comentários

Related Post

0
Adoraria saber sua opinião, comente.x