0 XP
Módulo 1 · Linux e Sistemas

Processos, sinais e systemd na prática

Intermediário 50 min+25 XPpstopkillsystemd

Objetivos desta aula

  • Investigar processos, estados e portas em uso
  • Enviar sinais corretamente e entender encerramento gracioso
  • Escrever uma unit systemd resiliente e segura
  • Operar o serviço: habilitar, reiniciar, verificar e ler logs

1. O que é um processo

Todo serviço em execução é um processo com PID (identificador), dono, processo pai, estado e consumo de recursos. Um container também é um processo — isolado por recursos do kernel, mas visível no host. Dominar processos é pré-requisito para entender containers e Kubernetes depois.

2. Ferramentas de inspeção

  • ps auxf — lista em forma de árvore, mostrando quem criou quem.
  • ps -eo pid,ppid,stat,etime,pcpu,pmem,cmd --sort=-pcpu — visão sob medida, ordenada por CPU.
  • top / htop — comportamento ao vivo.
  • pgrep -af node — localizar por nome.
  • ss -tulpn — quem escuta qual porta; resolve metade dos "a porta está em uso".

3. Estados que contam uma história

  • R executando ou pronto para executar.
  • S dormindo, esperando algo (normal).
  • D espera ininterrupta de I/O — indica disco ou rede lenta, não CPU.
  • Z zumbi: terminou, mas o pai não coletou o status.
  • T parado.

Muitos processos em D com CPU baixa é assinatura clássica de gargalo de armazenamento.

4. Sinais: conversando com processos

Sinal é uma notificação enviada ao processo. Os que importam: SIGTERM (15) pede encerramento e deixa o programa fechar conexões e terminar requisições; SIGKILL (9) mata imediatamente, sem chance de limpeza; SIGHUP (1) costuma significar "recarregue a configuração"; SIGINT (2) é o seu Ctrl+C.

Comece sempre por TERM. kill -9 pode corromper estado, deixar arquivo de lock preso e derrubar requisições no meio.

5. Encerramento gracioso na aplicação

Do lado do código, a aplicação deve escutar SIGTERM, parar de aceitar novas conexões, terminar as que estão em andamento e fechar o banco. Sem isso, cada deploy gera erro para quem estava navegando — e é exatamente o que Kubernetes espera do seu container.

6. Órfãos, zumbis e PID 1

Se o pai morre, o filho é adotado pelo PID 1 (init/systemd). Zumbis aparecem quando o pai não faz a coleta; em containers, isso é comum quando o processo principal não é preparado para ser PID 1 — daí a recomendação de usar --init ou um init mínimo na imagem.

7. O papel do systemd

systemd garante que o serviço suba no boot, reinicie após falha, tenha logs centralizados e dependências respeitadas. Sem ele você depende de alguém logar no servidor às 3h da manhã para digitar um comando.

8. Anatomia de uma unit

  • [Unit] — descrição e ordem (After, Wants).
  • [Service] — como executar: User, WorkingDirectory, EnvironmentFile, ExecStart, política de Restart.
  • [Install] — em qual alvo o serviço é habilitado (multi-user.target).

9. Política de restart sem laço maluco

Restart=on-failure com RestartSec=3 evita reinício instantâneo em loop. Para falhas persistentes, StartLimitBurst e StartLimitIntervalSec impedem que a máquina gaste CPU reiniciando algo que nunca vai subir. Teste com reboot: confiança se comprova, não se supõe.

10. Endurecimento (hardening) de graça

Quatro linhas que reduzem muito o risco: NoNewPrivileges=true (impede escalar privilégio), PrivateTmp=true (tmp isolado), ProtectSystem=full (sistema em leitura), ProtectHome=true. Adicione ReadWritePaths apenas para os diretórios que o serviço realmente precisa escrever.

11. Variáveis de ambiente do jeito certo

Use EnvironmentFile=/etc/cloudshop/app.env com permissão 640 e dono do serviço. Nunca coloque segredo direto em ExecStart: a linha de comando é visível em ps para qualquer usuário da máquina.

12. Rotina de operação e diagnóstico

daemon-reload após editar a unit, enable --now para habilitar e iniciar, status para ver estado e últimas linhas, journalctl -u ... -n 50 para o log, systemctl is-enabled para confirmar boot. Se o serviço não sobe, leia o log antes de mudar qualquer coisa.

Na prática

Investigação de processos

bash

ps auxf | head -30
ps -eo pid,ppid,stat,etime,pcpu,pmem,cmd --sort=-pcpu | head
# PID  PPID STAT ELAPSED %CPU %MEM CMD
# 1841    1 Ssl  02:14:11 87.4  6.1 /usr/bin/node /opt/cloudshop/server.js

ss -tulpn | grep :3000            # LISTEN 0 511 *:3000 users:(("node",pid=1841))
lsof -p 1841 | head               # arquivos e sockets abertos pelo processo
kill -TERM 1841                   # encerramento gracioso (sinal 15)
kill -KILL 1841                   # ultimo recurso (sinal 9)
pgrep -af node                    # localizar por nome
ps -eo stat | grep -c '^Z'        # quantidade de zumbis

Unit systemd da API do CloudShop

ini

# /etc/systemd/system/cloudshop-api.service
[Unit]
Description=CloudShop API
After=network-online.target
Wants=network-online.target

[Service]
User=cloudshop
Group=cloudshop
WorkingDirectory=/opt/cloudshop/current
EnvironmentFile=/etc/cloudshop/app.env
ExecStart=/usr/bin/node /opt/cloudshop/current/server.js
Restart=on-failure
RestartSec=3
StartLimitBurst=5
StartLimitIntervalSec=60
NoNewPrivileges=true
PrivateTmp=true
ProtectSystem=full
ProtectHome=true
ReadWritePaths=/var/log/cloudshop
StandardOutput=journal
StandardError=journal

[Install]
WantedBy=multi-user.target

Nota de segurança: EnvironmentFile deve ser 640, dono do serviço. Variáveis passadas em ExecStart aparecem em ps para qualquer usuário.

Operar o serviço

bash

sudo systemctl daemon-reload          # obrigatorio apos editar a unit
sudo systemctl enable --now cloudshop-api
systemctl status cloudshop-api --no-pager
# Active: active (running) since Sun 2026-09-06 10:22:01; 5s ago
sudo systemctl restart cloudshop-api
systemctl is-enabled cloudshop-api    # enabled -> sobe no boot
journalctl -u cloudshop-api -n 50 --no-pager

# Teste de resiliencia: mate o processo e veja o systemd trazer de volta
sudo kill -9 "$(systemctl show -p MainPID --value cloudshop-api)"
sleep 5 && systemctl is-active cloudshop-api    # active (reiniciado sozinho)

Encerramento gracioso na aplicação (Node)

javascript

const server = app.listen(3000);

async function shutdown(signal) {
  console.log(JSON.stringify({ level: "info", msg: "shutdown iniciado", signal }));
  server.close(async () => {          // para de aceitar novas conexoes
    try {
      await pool.end();               // fecha o pool do PostgreSQL
      process.exit(0);                // saida limpa: systemd registra sucesso
    } catch (e) {
      process.exit(1);
    }
  });
  setTimeout(() => process.exit(1), 10000).unref();  // limite de espera
}

process.on("SIGTERM", () => shutdown("SIGTERM"));  // systemd/Kubernetes enviam SIGTERM
process.on("SIGINT", () => shutdown("SIGINT"));    // Ctrl+C no terminal

Por que isso importa

Serviço que não volta sozinho depois de uma falha transforma incidente de dois minutos em madrugada perdida.

Erro comum

Sair matando com kill -9 e depois descobrir dados corrompidos ou lock file preso.

Dica de produção

Use Restart=on-failure com RestartSec para não entrar em laço de reinício agressivo, e sempre teste com reboot.

Pergunta de entrevista

Explique a diferença entre SIGTERM e SIGKILL e por que isso importa em deploy.

Glossário

unit
Arquivo de definição de um recurso gerenciado pelo systemd (serviço, timer, socket).
zumbi
Processo que terminou mas cujo status ainda não foi coletado pelo processo pai.
SIGTERM
Sinal que pede encerramento e permite ao programa finalizar com ordem.
SIGKILL
Sinal que encerra o processo imediatamente, sem oportunidade de limpeza.
daemon-reload
Comando que faz o systemd reler os arquivos de unit após uma alteração.
encerramento gracioso
Parar de aceitar novas requisições, concluir as em andamento e fechar recursos antes de sair.
load average
Média de processos prontos ou esperando execução, comparada ao número de núcleos.
socket em escuta
Porta aberta por um processo aguardando conexões, visível com ss -tulpn.

Conexão com o CloudShop

Colocar a API do CloudShop sob systemd, com restart automático e logs no journal.

Quiz da aula

  1. 1. Qual comando mostra qual processo está escutando a porta 3000?

  2. 2. Por que preferir SIGTERM a SIGKILL em um deploy?

  3. 3. Muitos processos em estado D com CPU baixa indicam o quê?

  4. 4. O que garante que o serviço volte sozinho depois de uma falha?

Minhas anotações

Salvo automaticamente neste navegador.

AnteriorPróxima