29/06/2026

Volume I — Parte 2 — Sistemas Operacionais, Redes de Computadores, Internet e Comunicação entre Sistemas

Voltar
Sumário do artigo

Parte 2 — Sistemas Operacionais, Redes de Computadores, Internet e Comunicação entre Sistemas

Foco: compreender o caminho completo de uma solicitação, do processo que a executa ao dado que persiste.
Abordagem: fundamentos rigorosos, comparação entre tecnologias, diagnóstico orientado por hipóteses, exemplos corporativos, notas Zettelkasten e exercícios de recuperação ativa.


Sumário


Prefácio — “O sistema caiu” não é um diagnóstico

Às 9h05, usuários informam que o portal de chamados não abre. Às 9h07, alguém conclui que “a Internet caiu”. Outro profissional reinicia o servidor. Um terceiro altera o DNS. Quinze minutos depois, descobre-se que o processo da aplicação estava ativo, o banco respondia e a rede funcionava: o proxy reverso encaminhava as requisições para uma porta antiga.

O episódio parece simples, mas revela um problema recorrente. A frase “o sistema caiu” descreve um efeito percebido; não identifica a camada, o componente nem a causa.

Uma aplicação corporativa depende de uma cadeia. O sistema operacional cria e isola processos; a rede transporta pacotes; o DNS transforma nomes em endereços; HTTP define a semântica da conversa; TLS protege o canal; a API recebe dados segundo um contrato; e o banco de dados preserva estados e relações. Uma falha em qualquer elo pode produzir a mesma percepção na tela do usuário.

Por isso, o objetivo desta parte não é decorar comandos, portas ou siglas. É aprender a construir um modelo causal:

  1. Qual resultado era esperado?
  2. Até qual camada o fluxo funcionou?
  3. Qual evidência separa uma hipótese de outra?
  4. O que mudou entre a última execução saudável e a falha?
  5. Como corrigir sem destruir evidências nem introduzir um segundo problema?

Ao concluir esta parte, você deverá ser capaz de:

  • explicar a relação entre processo, thread, memória virtual, arquivo e serviço;
  • diferenciar conectividade, resolução de nomes, transporte, segurança de canal e semântica HTTP;
  • comparar OSI e TCP/IP sem tratá-los como mapas literais da implementação;
  • distinguir switch, roteador, firewall, NAT, proxy e balanceador;
  • interpretar uma requisição HTTP e avaliar segurança e idempotência;
  • escolher entre API síncrona, webhook e processamento assíncrono;
  • separar autenticação, autorização, OAuth 2.0 e OpenID Connect;
  • modelar relações, consultar dados com JOIN e reconhecer multiplicação indevida de linhas;
  • explicar ACID, isolamento, índice, backup, RPO e RTO sem transformar definições em promessas irreais;
  • diagnosticar um incidente por camadas, com evidências reproduzíveis.

Limite editorial desta parte

Esta Parte 2 apresenta o suficiente de arquivos, containers, virtualização, nuvem e segurança para que o fluxo completo faça sentido. A arquitetura interna de sistemas de arquivos, hipervisores, modelos de serviço em nuvem, gestão aprofundada de identidades, criptografia e defesa em profundidade permanecem na Parte 3. Esse limite evita duas distorções: repetir conteúdo e tratar uma introdução como se fosse formação completa.


Mapa do percurso

Considere um analista que acessa o endereço https://suporte.exemplo.com/relatorios para consultar indicadores do GLPI:

flowchart TB
    A["Navegador"] --> B["DNS"]
    B --> C["Rede e gateway"]
    C --> D["Proxy e TLS"]
    D --> E["Processo e API"]
    E --> F["Banco de dados"]
    F --> G["Resposta HTTP"]

O fluxo é útil, mas ainda é uma simplificação. DNS pode usar caches; o proxy pode distribuir carga entre várias instâncias; a API pode publicar uma mensagem em vez de consultar imediatamente; o banco pode ser uma réplica; e a resposta pode vir de cache. O modelo deve ser detalhado apenas até o nível necessário para explicar o comportamento observado.

Pergunta operacional Camada inicialmente investigada Evidência típica
O processo existe e está executável? Sistema operacional estado, CPU, memória, descritor/porta, log do serviço
O destino é alcançável pelo caminho correto? Rede endereço, rota, perda, latência, conexão TCP/UDP
O nome aponta para o destino esperado? DNS resposta autoritativa, cache, TTL, tipo de registro
O servidor entendeu e aceitou a solicitação? HTTP/API método, status, headers, corpo, identificador de correlação
A identidade pode executar a ação? Autenticação e autorização credencial, escopo, papel, política e objeto solicitado
O estado foi lido ou alterado corretamente? Banco de dados consulta, plano, bloqueio, transação, restrição e log

Esse percurso será retomado em todos os capítulos. A meta é formar uma única visão de sistema, não cinco compartimentos de conhecimento.


Capítulo 5 — Sistemas Operacionais

Objetivos de aprendizagem

Ao final deste capítulo, você deverá conseguir:

  • explicar o sistema operacional como gestor de recursos e provedor de abstrações;
  • distinguir programa, processo, thread, serviço e container;
  • interpretar estados de execução e consumo de CPU, memória e entrada/saída;
  • explicar memória virtual, paginação, page fault, swap e thrashing;
  • relacionar permissões, identidade e acesso a arquivos;
  • usar logs, métricas e rastros como evidências complementares;
  • conduzir um diagnóstico inicial em Linux e Windows.

5.1 O problema que o sistema operacional resolve

Processador, memória, disco, interfaces de rede e dispositivos são recursos físicos finitos. Várias aplicações desejam utilizá-los ao mesmo tempo, mas não podem coordenar diretamente todos os detalhes do hardware sem risco de conflito. O sistema operacional oferece duas funções centrais:

  1. gerência: decide como recursos são compartilhados, protegidos e contabilizados;
  2. abstração: apresenta interfaces mais estáveis do que os detalhes de cada dispositivo.

Um programa pede para abrir um arquivo por nome; não escolhe manualmente setores físicos. Cria um socket; não programa o controlador da placa de rede. Solicita memória; não determina qual célula de RAM será usada. Essas abstrações tornam o software portátil e reduzem o acoplamento com o hardware [1][2].

Isso não significa que o sistema operacional elimine as diferenças físicas. Um disco lento continua impondo latência; a RAM continua limitada; e uma CPU saturada continua atrasando trabalho. A abstração organiza a complexidade, mas não revoga suas restrições.

Comparação: recurso físico e abstração

Recurso Abstração comum Pergunta de diagnóstico
CPU processo, thread, prioridade quem está executando e por quanto tempo?
RAM espaço de endereçamento e página virtual qual é o conjunto de trabalho e há pressão de memória?
armazenamento arquivo, diretório, volume há espaço, permissão e latência adequados?
rede interface, socket, rota qual endereço, porta, protocolo e caminho são usados?
dispositivo driver e handle o driver reconheceu e expôs o dispositivo?

5.2 Kernel, espaço de usuário e chamadas de sistema

Aplicações comuns executam em espaço de usuário, com privilégios limitados. O núcleo, ou kernel, controla operações sensíveis: escalonamento, memória, drivers, comunicação com dispositivos e mecanismos de proteção. Quando um processo precisa de uma operação privilegiada, utiliza uma interface de chamada de sistema.

Ao ler um arquivo, por exemplo, a aplicação não acessa o dispositivo diretamente:

  1. pede ao sistema para abrir um caminho;
  2. recebe um descritor ou handle;
  3. solicita a leitura de bytes;
  4. o kernel valida identidade, permissão e estado do objeto;
  5. o sistema de arquivos e o driver atendem a operação;
  6. os dados retornam ao processo.

A transição tem custo, mas a separação contém danos. Se qualquer aplicação pudesse reprogramar memória ou dispositivos sem mediação, um erro comum teria impacto sistêmico.

Exemplo: “o arquivo existe, mas a aplicação não lê”

Ver o arquivo com uma conta administrativa não prova que o serviço consegue lê-lo. O processo pode executar com outro usuário, dentro de outro namespace, com um diretório montado em caminho diferente ou sob uma política adicional. O diagnóstico deve observar a identidade e o ambiente reais do processo, não apenas a sessão interativa do analista.

5.3 Programa, processo, thread e serviço

Um programa é um conjunto de instruções armazenado. Um processo é uma instância em execução, com espaço de endereçamento, recursos e contexto próprios. Uma thread é um fluxo de execução dentro do processo; threads do mesmo processo normalmente compartilham memória e recursos, o que facilita comunicação e também cria riscos de concorrência. Em Windows, a documentação da API distingue explicitamente o objeto de processo, que representa recursos, do objeto de thread, que pode ser escalonado [3].

Um serviço é uma função de longa duração administrada por um gerenciador de serviços, como systemd no Linux ou Service Control Manager no Windows. O serviço possui política de inicialização, dependências, identidade, parâmetros e tratamento de falhas; o processo é uma de suas execuções concretas.

Conceito O que permanece O que pode variar em cada execução Exemplo
programa código e artefatos instalados — binário do Nginx
processo execução isolada e recursos PID, memória, descritores, estado um worker do Nginx
thread fluxo escalonável dentro do processo pilha, registradores, estado thread que atende uma requisição
serviço intenção operacional e política processo atual, tentativas, saúde unidade nginx.service

Estados de execução: um modelo, não uma lista universal

Modelos didáticos costumam usar novo, pronto, executando, bloqueado e encerrado. Sistemas reais expõem estados mais específicos. O ponto central é separar:

  • executando: está usando CPU neste instante;
  • executável/pronto: poderia usar CPU, mas aguarda ser escalonado;
  • bloqueado/dormindo: aguarda um evento, dado, temporizador ou recurso;
  • interrompido: foi suspenso por controle;
  • encerrado: terminou, embora metadados possam permanecer até serem coletados.

Um processo “dormindo” não está necessariamente com defeito. Servidores passam grande parte do tempo aguardando conexões ou entrada/saída. O problema nasce quando o estado observado contradiz o trabalho esperado — por exemplo, centenas de threads bloqueadas no mesmo pool de conexões.

5.4 Concorrência não é automaticamente paralelismo

Concorrência significa que múltiplas atividades progridem em intervalos sobrepostos. Paralelismo significa execução simultânea, geralmente em mais de um núcleo. Um único núcleo pode sustentar concorrência alternando tarefas; várias threads podem existir sem executar em paralelo.

Threads compartilham dados com baixo custo, mas duas delas podem ler e alterar o mesmo estado em ordem imprevisível. Considere um estoque igual a 1:

Thread A lê estoque = 1
Thread B lê estoque = 1
Thread A grava estoque = 0
Thread B grava estoque = 0

Duas vendas foram aceitas e o valor final ainda é zero. A sequência é uma condição de corrida. Locks, operações atômicas, filas, isolamento transacional e desenho sem estado compartilhado são estratégias possíveis; cada uma impõe custos e não substitui uma compreensão correta do invariante.

Outros problemas clássicos incluem:

  • deadlock: atividades aguardam recursos umas das outras sem possibilidade de progresso;
  • starvation: uma atividade permanece preterida;
  • livelock: há atividade, mas nenhuma aproximação do resultado;
  • contenção: muita concorrência disputa o mesmo recurso e reduz o ganho esperado.

5.5 Escalonamento: CPU alta, fila alta e espera não são a mesma coisa

O escalonador escolhe quais threads executáveis receberão CPU. Políticas reais consideram prioridade, interatividade, justiça, afinidade, deadlines e custo de alternância. Para análise inicial, três cenários devem ser separados:

Sintoma Interpretação possível Próxima evidência
CPU alta e trabalho útil cresce carga legítima throughput e latência
CPU alta e trabalho útil não cresce loop, contenção, coleta de lixo, erro repetitivo perfil, stacks, logs
CPU baixa e requisições lentas espera de banco, rede, disco, lock ou pool tempo por dependência
fila de executáveis alta demanda de CPU superior à capacidade disponível carga por núcleo e run queue

“O servidor tem 20% de CPU” também pode enganar: um processo monothread pode saturar um núcleo de uma máquina com muitos núcleos. Médias agregadas escondem pontos quentes.

5.6 Memória virtual, paginação e pressão de memória

Memória virtual não é apenas “RAM mais swap”. Ela oferece a cada processo um espaço de endereçamento, mapeia endereços virtuais para páginas físicas, possibilita proteção e permite compartilhar regiões de modo controlado. Uma página acessada pode já estar na RAM, ser carregada de um arquivo, ser materializada sob demanda ou exigir recuperação de armazenamento secundário [1][2].

Um page fault ocorre quando o mapeamento necessário não pode ser concluído imediatamente pela execução atual. Nem todo fault é grave:

  • um fault menor pode ser resolvido sem ler o disco, por exemplo associando uma página já presente;
  • um fault maior exige entrada/saída, com custo muito superior;
  • um acesso inválido pode encerrar o processo.

O sistema também usa RAM como cache de páginas de arquivos. Portanto, “memória usada” próxima do total não prova vazamento. É preciso observar memória disponível, cache recuperável, conjunto residente, taxa de faults, swap e evolução temporal.

Swap: mecanismo útil, não extensão equivalente à RAM

Swap pode retirar páginas pouco usadas da RAM e ganhar tempo diante de picos. Como armazenamento é muito mais lento que memória, atividade contínua de troca degrada a aplicação. Thrashing ocorre quando o sistema passa a movimentar páginas incessantemente e realiza pouco trabalho útil.

Indicador Pergunta correta
RSS/conjunto residente quanto da memória do processo está atualmente na RAM?
memória disponível quanto pode ser alocado sem pressão severa?
swap usada existe uso histórico ou troca ativa neste momento?
page-ins/page-outs a taxa sustenta hipótese de pressão?
OOM/encerramento o kernel ou limite do container matou o processo?

Em container, o host pode ter memória livre e, ainda assim, o processo atingir o limite do seu grupo de controle. O diagnóstico precisa incluir o limite efetivo, não apenas a capacidade física.

5.7 Arquivos, descritores e permissões

Arquivos fornecem persistência e uma interface para diferentes tipos de objeto. A aplicação acessa um caminho, o sistema resolve diretórios e permissões, e a operação ocorre por meio de um descritor ou handle. O objeto pode continuar aberto mesmo após renomeação ou exclusão do nome, conforme as regras do sistema.

Permissão não se resume a rwx. A decisão pode envolver proprietário, grupo, ACL, herança, token de acesso, identidade do serviço, montagem somente leitura e políticas adicionais. O princípio operacional é conceder apenas o necessário.

Exemplo: um serviço de relatórios do GLPI precisa ler configurações e gravar apenas em seu diretório de cache. Executá-lo como administrador porque “resolve o erro” amplia o impacto de uma vulnerabilidade e esconde a causa original.

A estrutura interna de sistemas de arquivos, journaling, RAID e volumes será aprofundada na Parte 3.

5.8 Serviços e dependências

Gerenciadores de serviços transformam processos em unidades operáveis. Eles podem iniciar após a rede, carregar variáveis, impor limites, reiniciar sob condições específicas e registrar a saída. Reiniciar indiscriminadamente, porém, apaga estado transitório e pode mascarar a falha.

Antes de reiniciar, registre:

  • horário e impacto;
  • estado e PID;
  • código da última saída;
  • consumo e limites;
  • conexões e portas;
  • mensagens imediatamente anteriores;
  • alteração recente de configuração ou dependência.

Depois, valide não apenas “ativo”, mas também capacidade de atender uma solicitação representativa. Um processo pode estar em execução e incapaz de acessar o banco.

5.9 Logs, métricas e rastros

Observabilidade não é sinônimo de logs. Os três sinais respondem a perguntas diferentes:

Sinal Estrutura Pergunta principal Exemplo
log evento com contexto o que aconteceu nesta execução? timeout ao consultar o GLPI
métrica série temporal agregável com que frequência e intensidade? p95 de latência, erros por minuto
rastro caminho de uma operação entre componentes onde o tempo foi gasto? proxy → API → banco → Slack

OpenTelemetry trata traces, metrics e logs como sinais relacionados e usa propagação de contexto para correlacionar uma operação distribuída [23]. Um request_id consistente permite seguir a mesma solicitação sem registrar dados sensíveis.

Logs úteis incluem instante com fuso, componente, severidade, operação, resultado e identificador de correlação. Senhas, tokens, conteúdo confidencial e dados pessoais não devem ser gravados por conveniência.

5.10 Container e máquina virtual: fronteiras diferentes

Um container é, essencialmente, um processo isolado por mecanismos do sistema operacional, empacotado com dependências e configuração. Containers compartilham o kernel do host; máquinas virtuais executam um sistema operacional convidado com seu próprio kernel. A documentação do Docker destaca exatamente essa diferença [4].

Critério Container Máquina virtual
kernel compartilhado com o host próprio do sistema convidado
unidade observada processo isolado máquina virtual completa
inicialização típica rápida mais pesada
fronteira de compatibilidade kernel compatível hardware virtualizado
isolamento namespaces, cgroups e políticas hipervisor e SO convidado

Compartilhar o kernel não significa “sem isolamento”, nem equivale à mesma fronteira de uma VM. Configuração privilegiada, montagem de sockets administrativos e execução como root elevam risco; a documentação de segurança do Docker enfatiza a importância de namespaces, capacidades e proteção do daemon [5]. Em Windows e macOS, ambientes de desenvolvimento de containers Linux normalmente utilizam uma VM subjacente.

Orquestração, imagens, volumes, redes de containers, hipervisores e cloud pertencem ao aprofundamento da Parte 3.

5.11 Diagnóstico inicial: Linux e Windows

Comandos são instrumentos de medição, não receitas. Registre horário, ambiente e hipótese antes de executá-los.

Linux

uptime
free -h
vmstat 1
ps -eo pid,ppid,user,stat,%cpu,%mem,rss,cmd --sort=-%cpu
ss -lntp
systemctl status nome-do-servico
journalctl -u nome-do-servico --since "30 minutes ago"

uptime contextualiza carga; free mostra a memória; vmstat permite observar evolução; ps relaciona consumo e processo; ss verifica escuta; systemctl mostra estado operacional; journalctl recupera eventos do serviço. Se iostat -xz 1 estiver disponível pelo pacote sysstat, ele ajuda a avaliar armazenamento.

Windows PowerShell

Get-Process | Sort-Object CPU -Descending | Select-Object -First 10
Get-Counter '\Processor(_Total)\% Processor Time'
Get-NetTCPConnection -State Listen
Get-Service -Name 'NomeDoServico'
Get-WinEvent -LogName Application -MaxEvents 50

Uma fotografia isolada raramente basta. Compare o momento do incidente com uma linha de base saudável e correlacione o relógio entre componentes.

Exemplo orientado por hipótese

Sintoma: https://suporte.exemplo.com devolve 502 Bad Gateway.

  1. O 502 prova que algum intermediário HTTP respondeu; DNS e parte do caminho funcionaram.
  2. Verifique no proxy qual upstream foi selecionado.
  3. Confirme se o processo da aplicação está ativo.
  4. Verifique se escuta no endereço e porta configurados.
  5. Teste o endpoint de saúde localmente, com timeout.
  6. Correlacione logs por horário e identificador.

Reiniciar o proxy no primeiro passo não testa a hipótese de porta incorreta.

5.12 Síntese do capítulo

  • O sistema operacional medeia recursos e oferece abstrações.
  • Processo é execução; thread é fluxo; serviço é política operacional de longa duração.
  • Concorrência, paralelismo e compartilhamento de estado são conceitos diferentes.
  • Memória virtual envolve mapeamento e proteção; swap não equivale à RAM.
  • Estado “ativo” não prova capacidade de atender.
  • Logs, métricas e rastros formam evidências complementares.
  • Container compartilha o kernel; VM possui kernel convidado.

Notas Zettelkasten — Capítulo 5

ZK-024 — Sistema operacional como mediador
Ideia: o SO combina abstração, alocação e proteção de recursos.
Conexões: ZK-025 — Processo e thread; ZK-027 — Comunicação em camadas.

ZK-025 — Processo, thread e serviço
Ideia: o programa é artefato; o processo é instância; a thread é fluxo;
o serviço expressa intenção operacional e política de ciclo de vida.
Conexões: ZK-026 — Pressão de memória; ZK-031 — Integração resiliente.

ZK-026 — Pressão de memória
Ideia: memória ocupada não basta; faults, swap ativa, conjunto residente,
limites e evolução temporal distinguem cache saudável de pressão real.
Conexões: ZK-025 — Processo e thread; ZK-033 — Capacidade e índice.

Recuperação ativa — Capítulo 5

  1. Por que um processo “dormindo” pode estar saudável?
  2. Qual é a diferença entre concorrência e paralelismo?
  3. Por que swap usada não prova, sozinha, thrashing?
  4. Como um serviço pode estar ativo e ainda indisponível?
  5. Qual evidência separa espera de CPU de espera de banco?
  6. Por que um container não é apenas uma VM pequena?

Tente responder sem consultar o texto. Depois, volte apenas às lacunas.


Capítulo 6 — Redes de Computadores

Objetivos de aprendizagem

Ao final deste capítulo, você deverá conseguir:

  • explicar comunicação em rede como composição de camadas e decisões;
  • comparar os modelos OSI e TCP/IP sem forçar equivalências;
  • distinguir LAN, VLAN, WAN e Internet;
  • interpretar endereço, prefixo, gateway, rota, porta e socket;
  • diferenciar switch, roteador, firewall, NAT, proxy e balanceador;
  • comparar TCP, UDP e QUIC sem reduzir a análise a “mais rápido”;
  • diagnosticar conectividade com testes que isolam hipóteses.

6.1 Rede é comunicação sob restrições

Uma rede permite que sistemas troquem dados mesmo quando estão separados por processos, máquinas, prédios ou provedores. Para que a comunicação ocorra, é necessário responder a várias perguntas:

  • identificação: qual interface, endereço e serviço participam?
  • enquadramento: como os bits são organizados no enlace local?
  • encaminhamento: qual caminho leva ao destino?
  • transporte: como os dados chegam a um processo e com quais garantias?
  • semântica: o que a mensagem significa para a aplicação?
  • controle: quem pode iniciar, atravessar e concluir a comunicação?

Essas decisões são distribuídas. O switch não interpreta a regra de negócio; o roteador não sabe se POST /tickets é autorizado; e o banco não escolhe a rota IP. O diagnóstico melhora quando cada componente é questionado apenas sobre a responsabilidade que realmente possui.

6.2 Modelos OSI e TCP/IP: mapas para raciocinar

O modelo OSI organiza funções de comunicação em sete camadas. A arquitetura TCP/IP, mais próxima da Internet real, costuma ser apresentada em quatro ou cinco. Nenhuma tabela é uma radiografia literal de todos os produtos; são modelos para separar responsabilidades [6][34].

OSI Função didática Aproximação no conjunto TCP/IP Exemplos
7. Aplicação protocolo usado pela aplicação aplicação HTTP, DNS, SMTP
6. Apresentação representação e transformação incorporada à aplicação/bibliotecas JSON, codificação, aspectos de TLS
5. Sessão coordenação de diálogos incorporada à aplicação/transporte sessão lógica, retomada
4. Transporte comunicação entre processos transporte TCP, UDP, QUIC sobre UDP
3. Rede endereçamento e roteamento Internet IPv4, IPv6, ICMP
2. Enlace entrega no segmento local acesso à rede Ethernet, Wi-Fi, VLAN
1. Física sinais e meio acesso à rede fibra, cobre, rádio

É comum afirmar que “TLS fica na camada de apresentação”. Isso pode ajudar em uma primeira aula, mas não descreve precisamente a implementação: TLS opera entre a aplicação e o transporte e atravessa responsabilidades que o OSI distribui. Do mesmo modo, uma VPN pode encapsular pacotes de uma camada dentro de outra. O valor do modelo está em orientar perguntas, não em obrigar cada tecnologia a ocupar uma única caixa.

Diagnóstico orientado pelo modelo

Se o cabo ou sinal falha, nenhuma correção em JSON resolverá. Se a conexão TCP abre, mas o servidor devolve 403, há conectividade até a aplicação e a hipótese deve migrar para identidade, autorização ou política. As camadas reduzem o espaço de busca.

6.3 LAN, VLAN, WAN e Internet

Uma LAN conecta dispositivos em uma área administrada, como escritório ou datacenter. Uma WAN interliga localidades por infraestrutura de terceiros ou enlaces de longa distância. A Internet é a rede global de redes autônomas, não uma única rede central.

Uma VLAN separa domínios de broadcast no enlace lógico, mesmo quando dispositivos compartilham switches físicos. Ela organiza tráfego e reduz exposição local, mas não é, sozinha, uma política de autorização. Se o roteamento entre VLANs estiver livre, um dispositivo de uma rede poderá alcançar a outra. ACLs, firewalls e políticas de identidade controlam o que atravessa a fronteira.

Exemplo corporativo

Considere três segmentos:

  • VLAN 10 — estações administrativas;
  • VLAN 20 — servidores de aplicação;
  • VLAN 30 — bancos de dados.

O desenho só produz isolamento relevante se o firewall permitir, por exemplo, estações → proxy em 443, proxy → aplicação na porta interna e aplicação → banco na porta necessária, bloqueando os demais fluxos. “Está em outra VLAN” não substitui a matriz de comunicação.

6.4 Endereço IP, prefixo e sub-rede

Um endereço IP identifica uma interface dentro de um contexto de roteamento. O prefixo informa quantos bits representam a rede. Em IPv4, 192.168.20.37/24 indica que os primeiros 24 bits formam o prefixo; nesse caso didático, a rede é 192.168.20.0/24.

Um /24 contém 256 combinações. Em uma sub-rede IPv4 tradicional, rede e broadcast não são atribuídos a hosts, restando 254 endereços usuais. Essa regra não deve ser generalizada para todo cenário: enlaces /31, rotas de host /32, ambientes virtuais e IPv6 possuem outros usos.

Os blocos privados IPv4 definidos pela RFC 1918 são [7]:

  • 10.0.0.0/8;
  • 172.16.0.0/12;
  • 192.168.0.0/16.

Eles não são roteados globalmente na Internet pública. Isso não os torna secretos nem seguros; são apenas espaços de endereçamento privados.

IPv6 não é “IPv4 com mais dígitos”

IPv6 possui endereços de 128 bits e muda práticas de autoconfiguração, descoberta de vizinhos, multicast e desenho de sub-redes. O endereço 2001:db8::10/64 usa o prefixo documental 2001:db8::/32. Embora este capítulo use IPv4 em exemplos por familiaridade, ambientes profissionais devem verificar as duas famílias: um nome pode resolver para A e AAAA, e a falha pode existir em apenas uma delas.

6.5 Entrega local, gateway e rota

Antes de enviar, o host compara o destino com suas rotas:

  • se o destino estiver diretamente conectado, procura o vizinho no enlace;
  • se estiver em outra rede, envia ao próximo salto, frequentemente o gateway padrão;
  • se houver rota mais específica, ela prevalece sobre a rota genérica.

Em IPv4, ARP associa endereços IP a endereços de enlace na rede local. Em IPv6, Neighbor Discovery realiza funções relacionadas. O gateway não “converte” automaticamente uma aplicação; ele encaminha pacotes conforme a tabela e políticas.

Exemplo: a aplicação 10.20.0.15/24 acessa o banco 10.30.0.20. Como o destino não pertence a 10.20.0.0/24, o pacote é enviado a um roteador. Se não houver rota de retorno da rede do banco para a aplicação, a ida pode ocorrer e a conexão ainda falhar. Conectividade é bidirecional.

6.6 Switch, roteador, firewall, NAT, proxy e balanceador

Esses componentes podem coexistir no mesmo produto, mas as funções devem permanecer distintas.

Componente/função Decisão principal Exemplo de evidência
switch para qual porta encaminhar o quadro local tabela de endereços MAC
roteador qual próximo salto usar entre redes tabela de rotas
firewall qual fluxo permitir, negar ou inspecionar regra e log de sessão
NAT como traduzir endereços e/ou portas tabela de traduções
proxy como intermediar uma conversa da aplicação log de requisição e upstream
balanceador qual instância saudável receberá a solicitação algoritmo, pool e health check

Um firewall pode fazer NAT, e um proxy reverso pode balancear carga. Ainda assim, dizer “o firewall traduziu o IP, logo protegeu o serviço” mistura mecanismos. NAT traduz; política de firewall controla. Uma tradução pode reduzir exposição incidental, mas não substitui autorização, atualização ou filtragem.

Proxy direto representa o cliente diante de destinos. Proxy reverso representa servidores diante do cliente. O primeiro costuma controlar saída; o segundo publica e protege a entrada de aplicações.

6.7 TCP, UDP e QUIC

TCP

TCP oferece um fluxo confiável e ordenado de bytes entre endpoints. Estabelece conexão, retransmite perdas e aplica controle de fluxo e congestionamento. A especificação atual consolidada está na RFC 9293 [8]. “Confiável” não significa que a aplicação sempre terá sucesso: timeouts, encerramentos, falhas do processo e transações incompletas continuam possíveis.

UDP

UDP fornece datagramas com cabeçalho e mecanismo básicos, sem garantia incorporada de entrega, ordem, controle de fluxo ou retransmissão [9]. Descrevê-lo apenas como “mais rápido” é insuficiente. O menor conjunto de garantias reduz algumas despesas, mas desempenho depende da aplicação, da rede e do protocolo construído sobre ele.

DNS frequentemente usa UDP para consultas comuns e pode usar TCP quando necessário. Voz em tempo real pode preferir descartar um pacote atrasado a esperar retransmissão. Uma aplicação também pode implementar suas próprias confirmações sobre UDP.

QUIC

QUIC utiliza UDP como base, mas implementa transporte seguro, controle de congestionamento e fluxos confiáveis no espaço de usuário. HTTP/3 faz o mapeamento de HTTP sobre QUIC [14]. Portanto, observar UDP não permite concluir que a aplicação abriu mão de confiabilidade.

Critério TCP UDP QUIC
unidade para a aplicação fluxo de bytes datagrama fluxos sobre conexão QUIC
entrega ordenada sim, no fluxo não incorporada por fluxo confiável
retransmissão incorporada não incorporada pelo QUIC
segurança separada, normalmente TLS separada TLS 1.3 integrado ao protocolo
exemplo PostgreSQL, HTTP/1.1 e HTTP/2 DNS, telemetria específica HTTP/3

6.8 Portas, endpoints e sockets

O endereço identifica uma interface; a porta ajuda a selecionar o serviço de transporte no host. Um endpoint pode ser representado por protocolo, endereço e porta, como TCP 10.20.0.15:443. Uma conexão TCP é distinguida pelo conjunto de endereços e portas de origem e destino.

Portas conhecidas são convenções, não garantias. HTTPS costuma usar 443, mas pode operar em outra porta. Encontrar 443 aberta não prova que há HTTPS válido; é necessário realizar a negociação e verificar a aplicação.

Outra distinção importante:

  • escutar em 127.0.0.1: aceita apenas conexões locais;
  • escutar em um endereço específico: aceita naquela interface;
  • escutar em 0.0.0.0: aceita em todas as interfaces IPv4 compatíveis, sujeito a firewall e rota.

É comum um container estar saudável internamente e inacessível porque a porta não foi publicada ou o processo escuta apenas no loopback interno.

6.9 NAT e o caminho de ida e volta

NAT altera endereços e, em muitos casos, portas. Em uma saída IPv4 compartilhada, vários clientes privados podem usar um endereço público com traduções diferentes. O equipamento mantém estado suficiente para devolver cada resposta ao fluxo correto.

Consequências práticas:

  • o servidor pode enxergar o IP do tradutor, não o cliente original;
  • conexões iniciadas externamente exigem publicação ou regra apropriada;
  • logs de diferentes camadas precisam de horário e contexto para correlacionar traduções;
  • NAT quebrado, timeout de estado ou rota assimétrica podem afetar apenas alguns fluxos.

Para HTTP por proxy, headers como Forwarded ou X-Forwarded-For podem transportar a origem declarada. A aplicação só deve confiar neles quando foram removidos e reescritos por proxies conhecidos; qualquer cliente pode enviar um header arbitrário.

6.10 Diagnóstico por hipóteses

Uma sequência útil vai do escopo ao protocolo de aplicação:

1. Delimite o impacto

  • um usuário, uma rede, um provedor ou todos?
  • IPv4, IPv6 ou ambos?
  • um nome, um IP, uma porta ou todas as aplicações?
  • começou após qual mudança?

2. Observe configuração local

Linux:

ip addr
ip route
ss -s

Windows PowerShell:

Get-NetIPConfiguration
Get-NetRoute
Get-NetTCPConnection

3. Teste cada hipótese

ping -c 4 10.20.0.15
traceroute 10.20.0.15
nc -vz 10.20.0.15 443
curl -sS -D - -o /dev/null https://suporte.exemplo.com/

No Windows:

Test-NetConnection suporte.exemplo.com -Port 443
Resolve-DnsName suporte.exemplo.com

Interprete os limites:

  • falha de ping não prova indisponibilidade; ICMP pode ser filtrado ou limitado;
  • sucesso de ping não prova que a porta da aplicação está aberta;
  • conexão TCP bem-sucedida não prova que TLS ou HTTP estão corretos;
  • resposta HTTP de erro prova que uma aplicação respondeu, o que já elimina hipóteses inferiores.

Captura de pacotes pode mostrar SYN sem resposta, retransmissões, resets ou negociação. Ela deve obedecer à política de privacidade, pois pacotes podem conter dados sensíveis.

Matriz de evidências

Resultado O que sustenta O que ainda não prova
nome resolve para IP correto DNS respondeu conforme a visão consultada rota, porta, TLS e aplicação
TCP 443 conecta caminho e política permitem o handshake TCP certificado, HTTP e autorização
TLS negocia e certificado valida canal e identidade do servidor foram verificados regra de negócio e banco
HTTP retorna 401 servidor HTTP recebeu e exige credencial válida que o usuário tem autorização
endpoint retorna 200 aquela operação concluiu segundo o servidor saúde de todas as dependências

6.11 Síntese do capítulo

  • OSI e TCP/IP são modelos úteis, não encaixes literais.
  • VLAN separa o enlace; firewall e ACL controlam travessia.
  • Endereço, prefixo, rota, porta e protocolo respondem a perguntas diferentes.
  • NAT não é um sinônimo de segurança.
  • UDP não é apenas “TCP mais rápido e sem conexão”.
  • QUIC mostra que garantias podem ser construídas sobre UDP.
  • Um teste vale pelo conjunto de hipóteses que elimina.

Notas Zettelkasten — Capítulo 6

ZK-027 — Comunicação em camadas
Ideia: cada camada assume responsabilidades e fornece uma interface;
diagnosticar é localizar a primeira promessa que deixou de ser cumprida.
Conexões: ZK-024 — Sistema operacional; ZK-028 — Resolução de nomes.

ZK-028 — Endereço, rota e serviço
Ideia: alcançar um IP, abrir uma porta e concluir uma operação são evidências
distintas; nenhuma deve ser usada como prova das demais.
Conexões: ZK-027 — Comunicação em camadas; ZK-029 — Semântica HTTP.

Recuperação ativa — Capítulo 6

  1. Por que OSI e TCP/IP não devem ser mapeados como equivalentes perfeitos?
  2. Que controle falta quando dois servidores estão em VLANs diferentes, mas o roteamento é irrestrito?
  3. Por que NAT não deve ser citado como controle principal de segurança?
  4. O que uma conexão TCP bem-sucedida prova — e o que não prova?
  5. Como uma aplicação pode ter entrega confiável sobre UDP?
  6. Por que a rota de retorno faz parte do diagnóstico?

Capítulo 7 — Internet, DNS, HTTP e HTTPS

Objetivos de aprendizagem

Ao final deste capítulo, você deverá conseguir:

  • explicar Internet, sistema autônomo e BGP em nível conceitual;
  • reconstruir o caminho de uma resolução DNS e interpretar caches e TTL;
  • separar semântica HTTP das versões de transporte;
  • analisar método, alvo, headers, status e corpo;
  • distinguir métodos seguros e idempotentes;
  • explicar o papel de TLS, certificados e proxy reverso;
  • diagnosticar um fluxo Web do nome até o upstream.

7.1 Internet: uma rede de redes

A Internet conecta redes administradas independentemente. Cada sistema autônomo aplica políticas e troca informações de alcançabilidade com outros. BGP é o protocolo que sustenta grande parte desse roteamento entre domínios.

Em nível operacional, isso significa que não existe um único “caminho da Internet”. Rotas podem mudar, ser filtradas, anunciadas incorretamente ou diferir conforme origem e família IP. Uma aplicação pode funcionar a partir de um provedor e falhar em outro.

Para o analista de sistemas, o detalhe importante é a divisão de responsabilidades:

  • DNS descobre um endereço;
  • roteamento encontra um caminho;
  • transporte conecta processos;
  • TLS protege e autentica o canal;
  • HTTP expressa a operação.

7.2 DNS: nomes, dados distribuídos e cache

DNS é um banco de dados hierárquico e distribuído que associa nomes a dados. As RFCs 1034 e 1035 definiram sua arquitetura original; a RFC 9499 atualiza a terminologia usada no ecossistema [10][11].

Quando uma aplicação consulta suporte.exemplo.com, o fluxo típico é:

  1. a aplicação consulta caches locais ou o resolvedor configurado;
  2. um resolvedor recursivo procura uma resposta em cache;
  3. se necessário, consulta a hierarquia e os servidores autoritativos;
  4. devolve a resposta e a armazena pelo tempo permitido;
  5. a aplicação escolhe um endereço compatível e tenta conectar.

O servidor recursivo busca respostas em nome do cliente. O servidor autoritativo publica os dados oficiais de uma zona. O arquivo hosts, cache do navegador, resolvedor local e DNS corporativo podem produzir visões diferentes.

Registros frequentes

Tipo Finalidade Exemplo conceitual
A nome para IPv4 suporte → 203.0.113.10
AAAA nome para IPv6 suporte → 2001:db8::10
CNAME alias para outro nome portal → proxy.exemplo.com
MX servidores de e-mail do domínio prioridade e host de entrega
TXT texto associado ao nome verificação, SPF e outros usos
NS servidores autoritativos da zona delegação
SOA parâmetros administrativos da zona serial e tempos relacionados

TTL e a chamada “propagação”

Após uma alteração, caches antigos podem continuar válidos até expirar. A expressão “aguardar a propagação” é popular, mas imprecisa: frequentemente o que se aguarda é a expiração de respostas armazenadas conforme o TTL. Também podem existir delegação incorreta, servidor autoritativo divergente, cache negativo e resolvers com políticas próprias.

Reduzir o TTL minutos antes da mudança não elimina caches já criados com o valor anterior. Planejamento deve começar pelo menos um TTL antigo antes.

Diagnóstico DNS

dig suporte.exemplo.com A
dig suporte.exemplo.com AAAA
dig @servidor-recursivo suporte.exemplo.com
dig +trace suporte.exemplo.com

+trace reproduz parte da caminhada iterativa a partir do ambiente consultado; não mostra necessariamente a visão do cliente nem substitui uma consulta ao resolvedor real. Compare resposta, servidor, TTL, autoridade e família IP.

7.3 HTTP: semântica independente da versão

HTTP define uma interface de mensagens entre cliente e servidor. A RFC 9110 descreve sua semântica comum [12]. HTTP/1.1, HTTP/2 e HTTP/3 preservam métodos, status e campos, mas mudam enquadramento e transporte:

Versão Transporte e enquadramento Característica relevante
HTTP/1.1 texto sobre TCP conexões persistentes e pipelining limitado
HTTP/2 frames binários sobre TCP multiplexação de streams e compressão de headers [13]
HTTP/3 HTTP sobre QUIC/UDP multiplexação sem bloqueio entre streams causado por perda TCP [14]

Uma API não se torna semanticamente diferente apenas porque foi negociado HTTP/2. O servidor ainda precisa compreender o método, o alvo e o conteúdo.

7.4 Anatomia de uma requisição e de uma resposta

Exemplo conceitual:

GET /api/v1/tickets?status=open&limit=20 HTTP/1.1
Host: suporte.exemplo.com
Accept: application/json
Authorization: Bearer <token>
X-Request-ID: 7f9c...

Uma requisição contém:

  • método;
  • alvo, incluindo caminho e consulta;
  • versão no caso representado;
  • campos de cabeçalho;
  • corpo opcional.

Uma resposta pode ser:

HTTP/1.1 200 OK
Content-Type: application/json
Cache-Control: private, no-store
X-Request-ID: 7f9c...

{"items": [], "next_cursor": null}

Content-Type descreve a representação enviada; Accept expressa formatos aceitos pelo cliente. Um corpo JSON com header de texto incorreto pode ser interpretado de forma inesperada por intermediários e clientes.

7.5 Métodos: segurança e idempotência

Em HTTP, seguro significa que o cliente não solicita mudança de estado no servidor. Idempotente significa que múltiplas solicitações idênticas têm o mesmo efeito pretendido de uma única, ainda que cada resposta possa variar [12].

Método Uso comum Seguro Idempotente
GET obter representação sim sim
HEAD obter metadados sem corpo da representação sim sim
PUT criar/substituir estado no alvo conhecido não sim
DELETE remover estado identificado não sim
POST processar comando ou criar sob coleção não não por definição
PATCH aplicar modificação parcial não depende da semântica do patch

Repetir DELETE /tickets/42 pode devolver 204 e depois 404, mas o estado pretendido — recurso ausente — permanece. Idempotência não exige respostas idênticas.

Atualização contemporânea: método QUERY

A RFC 10008, publicada em 2026, define QUERY como método seguro e idempotente para executar uma consulta cujo conteúdo pode viajar no corpo [16]. Ele atende casos em que a consulta é grande ou sensível demais para a URI. A existência de um padrão não significa adoção imediata por frameworks, caches, proxies e gateways; compatibilidade deve ser medida antes de uso em produção.

7.6 Códigos de status são parte do contrato

Faixa Sentido Exemplos
1xx informação provisória 100 Continue
2xx solicitação processada 200 OK, 201 Created, 204 No Content
3xx redirecionamento ou uso de representação existente 301, 302, 304
4xx problema relacionado à solicitação/cliente 400, 401, 403, 404, 409, 429
5xx servidor não cumpriu solicitação válida 500, 502, 503, 504

Distinções úteis:

  • 400 Bad Request: sintaxe ou conteúdo inválido;
  • 401 Unauthorized: credenciais de autenticação ausentes ou inválidas — o nome histórico é confuso;
  • 403 Forbidden: o servidor compreendeu, mas recusa autorizar;
  • 404 Not Found: recurso não encontrado ou deliberadamente não revelado;
  • 409 Conflict: estado atual conflita com a operação;
  • 422 Unprocessable Content: conteúdo reconhecido, mas semanticamente inválido;
  • 429 Too Many Requests: limite de requisições atingido;
  • 502 Bad Gateway: intermediário recebeu resposta inválida do upstream;
  • 503 Service Unavailable: serviço temporariamente indisponível;
  • 504 Gateway Timeout: intermediário não recebeu resposta em tempo.

O status não basta para investigar. Corpo de erro estruturado, documentação e request_id completam a evidência.

7.7 Headers, cache e confiança entre proxies

Headers transportam metadados de representação, negociação, cache, identidade e rastreio. Exemplos:

  • Authorization: credencial apresentada;
  • Content-Type: tipo do corpo enviado;
  • Accept: representações aceitáveis;
  • Cache-Control: diretivas de cache;
  • ETag e If-None-Match: validação condicional;
  • Location: URI associada a redirecionamento ou criação;
  • Retry-After: orientação de nova tentativa;
  • traceparent ou identificador equivalente: correlação distribuída.

Headers de encaminhamento merecem fronteira explícita. Um proxy confiável pode definir host, protocolo e IP originais; a aplicação deve rejeitar valores que não vieram da cadeia autorizada. O módulo de proxy do Nginx permite controlar os campos enviados ao upstream [32].

7.8 HTTPS, TLS e certificados

HTTPS é HTTP sobre um canal protegido por TLS. No uso Web comum, TLS fornece:

  • confidencialidade contra observação do conteúdo em trânsito;
  • integridade contra modificação não detectada;
  • autenticação do servidor por cadeia de certificados e validação do nome;
  • autenticação opcional do cliente, quando mTLS é configurado.

A especificação corrente de TLS 1.3 é a RFC 9846, que em 2026 substituiu a RFC 8446 [15]. A versão do padrão não garante que qualquer servidor esteja corretamente configurado.

O que o cliente valida

Em linhas gerais:

  1. o certificado é válido no período atual;
  2. o nome solicitado está coberto;
  3. a cadeia leva a uma autoridade confiável;
  4. assinaturas e parâmetros são aceitáveis;
  5. políticas locais de revogação e segurança são aplicadas.

Erros comuns incluem certificado expirado, cadeia intermediária ausente, nome incorreto, relógio do host errado e inspeção TLS corporativa não confiada pelo cliente.

O que HTTPS não resolve

TLS não corrige autorização quebrada, injeção SQL, lógica de negócio incorreta, XSS, vazamento em logs nem servidor comprometido. Ele protege o canal entre participantes autenticados nos termos da configuração; não garante que a aplicação seja correta.

Em diagnóstico, curl -vk pode revelar negociação e cadeia, mas -k desativa validação. Use apenas para isolar hipótese e jamais transforme isso em configuração permanente.

7.9 Proxy reverso e caminhos de aplicação

O proxy reverso recebe solicitações públicas e as encaminha a um ou mais upstreams. Pode terminar TLS, normalizar headers, limitar requisições, armazenar cache e balancear carga.

Uma falha recorrente ocorre quando a aplicação vive sob um prefixo:

Cliente solicita: /relatorios/tickets
Proxy envia:      /tickets
Aplicação espera: /relatorios/tickets

Ou o inverso. Barras finais, reescrita de caminho, Host, protocolo original e geração de URLs precisam concordar. Um redirecionamento infinito muitas vezes indica que o proxy informa HTTP ao upstream enquanto o cliente usa HTTPS, ou que ambos tentam acrescentar/remover o mesmo prefixo.

Exemplo Nginx conceitual

location /relatorios/ {
    proxy_pass http://relatorios_app/;
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_set_header X-Request-ID $request_id;
}

O efeito da barra em proxy_pass deve ser validado na documentação e em teste. A aplicação também precisa confiar somente no proxy conhecido antes de usar headers para construir URLs ou registrar o cliente.

7.10 Do nome à resposta: leitura completa

Para https://suporte.exemplo.com/api/v1/tickets/42:

  1. o cliente resolve o nome, talvez usando cache;
  2. escolhe IPv4 ou IPv6 e consulta a rota;
  3. estabelece transporte com o endereço e a porta;
  4. negocia TLS e valida a identidade do servidor;
  5. envia método, alvo, headers e corpo;
  6. o proxy seleciona um upstream saudável;
  7. a aplicação autentica, autoriza e executa a operação;
  8. dependências retornam ou falham;
  9. a resposta atravessa o caminho inverso;
  10. o cliente interpreta status, headers e representação.

Esse fluxo permite perguntas precisas: “o nome resolveu?”, “o TLS validou?”, “qual upstream respondeu?”, “qual status e request_id foram devolvidos?”. A pergunta “a Internet está normal?” é ampla demais.

7.11 Síntese do capítulo

  • DNS é distribuído e cacheado; “propagação” costuma significar expiração de cache.
  • HTTP define semântica; suas versões mudam transporte e enquadramento.
  • Seguro e idempotente são propriedades diferentes.
  • 401 trata de credencial de autenticação; 403, de recusa de autorização.
  • TLS protege o canal, mas não corrige vulnerabilidades da aplicação.
  • Proxy reverso cria uma fronteira que precisa tratar caminhos e headers explicitamente.

Notas Zettelkasten — Capítulo 7

ZK-029 — Nome, endereço e identidade
Ideia: DNS descobre um destino; roteamento o alcança; TLS autentica o par;
nenhuma dessas etapas autoriza uma operação de negócio.
Conexões: ZK-028 — Endereço, rota e serviço; ZK-030 — Contrato de API.

ZK-030 — Semântica HTTP
Ideia: método, status e headers formam um contrato independente do mecanismo
de transporte; idempotência descreve efeito pretendido, não resposta igual.
Conexões: ZK-029 — Nome, endereço e identidade; ZK-031 — Integração resiliente.

Recuperação ativa — Capítulo 7

  1. Qual é a diferença entre DNS recursivo e autoritativo?
  2. Por que “propagação de DNS” pode ser uma descrição imprecisa?
  3. O que HTTP/3 preserva e o que muda em relação a HTTP/2?
  4. Por que DELETE pode ser idempotente mesmo devolvendo status diferentes?
  5. O que diferencia 401, 403 e 404?
  6. Quais problemas permanecem possíveis mesmo com TLS válido?

Capítulo 8 — APIs, REST, JSON e Integrações

Objetivos de aprendizagem

Ao final deste capítulo, você deverá conseguir:

  • explicar API como fronteira contratual entre capacidades;
  • reconhecer as restrições de REST e evitar reduzi-lo a URLs com JSON;
  • comparar REST, RPC, GraphQL, webhooks e mensageria;
  • distinguir integração síncrona de assíncrona;
  • separar autenticação, autorização, OAuth 2.0 e OpenID Connect;
  • projetar timeout, retentativa, idempotência e tratamento de duplicatas;
  • estabelecer observabilidade e versionamento compatíveis com evolução;
  • avaliar uma integração entre GLPI, n8n, Slack e IA.

8.1 API é uma fronteira, não apenas um endpoint

Uma Application Programming Interface expõe capacidades de um componente para outro por meio de regras compreensíveis. Uma API Web é uma forma importante, mas não a única: bibliotecas, sistemas operacionais, drivers e bancos também expõem interfaces programáticas.

Uma API útil especifica mais do que a URL:

  • operações disponíveis e sua semântica;
  • forma e tipos de entrada;
  • representação de saída;
  • erros possíveis;
  • autenticação e autorização;
  • limites, paginação e quotas;
  • comportamento diante de duplicatas;
  • compatibilidade e ciclo de vida;
  • nível de serviço e observabilidade.

Uma rota que “funciona quando testada manualmente” ainda pode ser um contrato ruim se omite limites, altera campos sem aviso ou devolve 200 com erro dentro do corpo.

Exemplo de contrato

POST /api/v1/tickets
Idempotency-Key: 8e1e2c1d-...
Content-Type: application/json

{
  "title": "Falha no acesso ao ERP",
  "category_id": 17,
  "requester_id": 804
}

Possíveis resultados documentados:

  • 201 Created e Location: /api/v1/tickets/9821;
  • 400 Bad Request para JSON malformado;
  • 401 para credencial inválida;
  • 403 para identidade sem permissão;
  • 409 para conflito de idempotência ou estado;
  • 422 para categoria inexistente ou regra semântica violada;
  • 429 para limite excedido;
  • 503 para dependência temporariamente indisponível.

O contrato permite que cliente e servidor evoluam com menos suposições ocultas.

8.2 Descrição de interface e OpenAPI

A OpenAPI Specification fornece uma descrição independente de linguagem para APIs HTTP. A versão publicada mais recente em agosto de 2026 é a 3.2.0 [18]. Um documento pode registrar caminhos, operações, parâmetros, schemas, respostas e mecanismos de segurança.

Isso ajuda a:

  • revisar o contrato antes do código;
  • gerar documentação e clientes;
  • validar exemplos e schemas;
  • automatizar testes de compatibilidade;
  • comparar versões.

Entretanto, a especificação não prova que a implementação obedece ao contrato nem que a semântica de negócio é boa. Testes e monitoramento continuam necessários.

Exemplo reduzido:

openapi: 3.1.0
info:
  title: API de Relatórios
  version: 1.0.0
paths:
  /tickets/{ticketId}:
    get:
      parameters:
        - in: path
          name: ticketId
          required: true
          schema: { type: integer }
      responses:
        '200': { description: Chamado encontrado }
        '404': { description: Chamado não encontrado }

O exemplo usa 3.1.0 porque continua comum no ecossistema; adotar 3.2.0 depende do suporte das ferramentas. Versão do documento e versão da API são decisões diferentes.

8.3 REST: estilo arquitetural, não sinônimo de CRUD

REST foi descrito por Roy Fielding como um estilo para sistemas distribuídos em hipermídia. Suas restrições incluem cliente-servidor, ausência de estado de sessão no servidor entre solicitações, cache, interface uniforme, camadas e código sob demanda opcional [17].

Três correções são essenciais:

  1. REST não exige JSON. Um recurso pode ter representações em JSON, HTML, XML ou outro formato.
  2. URLs com substantivos e métodos HTTP não bastam. É necessário considerar as restrições, sobretudo interface uniforme e mensagens autodescritivas.
  3. Stateless não significa ausência de estado. O servidor mantém estado de recursos; o que não deve depender de uma sessão conversacional oculta é a compreensão de cada solicitação.

Recurso e representação

/tickets/42 identifica conceitualmente um recurso. O JSON recebido é uma representação de seu estado em determinado instante:

{
  "id": 42,
  "status": "assigned",
  "title": "Falha no acesso ao ERP",
  "links": {
    "self": "/api/v1/tickets/42",
    "comments": "/api/v1/tickets/42/comments"
  }
}

O recurso não é o arquivo JSON. Essa distinção permite múltiplas representações e evolução independente da persistência.

Níveis de aderência e pragmatismo

Muitas APIs chamadas “REST” são, na prática, APIs HTTP orientadas a recursos. Isso não as torna inutilizáveis. A linguagem deve apenas ser precisa: se a API não usa hipermídia como motor de transição, ela implementa parte do estilo, não todas as restrições descritas por Fielding.

8.4 REST, RPC, GraphQL e eventos: comparação

Não existe um padrão universalmente superior. A escolha depende da forma de interação, do acoplamento e das garantias necessárias.

Abordagem Unidade central Pontos fortes Custos e riscos Exemplo adequado
REST/HTTP orientado a recursos recurso e representação semântica Web, cache e interoperabilidade sub/sobrebusca, aderência parcial frequente catálogo e chamados
RPC procedimento/comando intenção explícita, mapeamento natural de operações acoplamento a comandos e versionamento recalculateSla interno
GraphQL grafo e consulta do cliente seleção flexível de campos custo de consulta, cache e autorização por campo portal que agrega múltiplas visões
webhook notificação HTTP enviada pelo produtor baixa latência sem polling constante duplicata, assinatura, replay e indisponibilidade do receptor avisar ticket criado
fila/event stream mensagem persistida desacoplamento temporal e absorção de picos consistência eventual, ordenação e operação do broker classificar tickets em segundo plano

Um comando de negócio como POST /tickets/42/close pode ser mais claro que forçar uma atualização genérica de status, embora não seja uma modelagem purista. O contrato deve tornar precondições e efeitos explícitos.

8.5 JSON: sintaxe simples, contrato ainda necessário

JSON representa objetos, arrays, strings, números, booleanos e null; sua gramática é padronizada pela RFC 8259 [19]. Ele não carrega, por si só, tipos como data, moeda, UUID ou decimal exato.

Considere:

{
  "opened_at": "2026-08-28T09:15:00-03:00",
  "estimated_hours": 1.5,
  "priority": 3,
  "requester": null
}

O contrato precisa explicar:

  • formato e fuso da data;
  • escala e unidade do decimal;
  • faixa válida de prioridade;
  • diferença entre campo ausente e null;
  • campos obrigatórios e adicionais;
  • tamanho máximo e codificação.

Valores monetários não devem depender de ponto flutuante binário sem decisão consciente. Uma alternativa é decimal no banco e string decimal ou unidade inteira mínima no contrato.

Validação em fronteiras

Validar JSON significa verificar sintaxe e semântica. {"priority": 999} é JSON válido, mas pode violar o domínio. Rejeite cedo, devolva erro estruturado e não confie em campos de identidade enviados pelo cliente quando eles devem vir da credencial.

8.6 Sincronismo, assincronismo e webhooks

Em uma integração síncrona, o solicitante aguarda o resultado no mesmo ciclo de interação. É apropriada quando o resultado imediato é necessário e o tempo de resposta é previsível.

Em uma integração assíncrona, o trabalho é aceito e concluído depois. O solicitante recebe um identificador ou evento e consulta o estado posteriormente.

Pergunta Síncrono Assíncrono
resposta final imediata natural não
absorção de picos limitada por pools e timeouts melhor com fila durável
acoplamento temporal alto menor
modelo de erro na resposta estado, evento, retry ou fila de falhas
complexidade operacional inicialmente menor maior

Exemplo: abrir um chamado pode ser síncrono até persistir o registro e retornar 201. Classificação por IA, envio ao Slack e atualização de indicadores podem ser assíncronos. Assim, indisponibilidade do Slack não impede a criação do chamado.

Webhook robusto

Webhook é uma chamada iniciada pelo produtor quando ocorre um evento. O receptor deve assumir que mensagens podem atrasar, duplicar ou chegar fora de ordem.

Boas práticas:

  1. usar HTTPS;
  2. assinar o corpo com segredo ou chave e validar sobre os bytes exatos;
  3. incluir timestamp e rejeitar replays fora da janela;
  4. atribuir event_id único;
  5. responder rapidamente após persistir/encaminhar;
  6. processar de forma idempotente;
  7. aplicar retentativas limitadas com backoff e jitter;
  8. manter fila de falhas e procedimento de reprocessamento.

Filtrar por IP pode complementar, mas não substituir assinatura e autenticação quando os endereços mudam ou são compartilhados.

8.7 Autenticação e autorização

Autenticação responde “quem ou o que apresenta esta identidade?”. Autorização responde “essa identidade pode executar esta ação sobre este objeto neste contexto?”.

Um técnico autenticado pode editar chamados de sua entidade, mas não ler chamados confidenciais de outra. Verificar apenas “usuário logado” é insuficiente; a autorização deve alcançar o objeto.

Mecanismo/conceito Função Erro comum
senha + sessão autenticar usuário e manter sessão sessão sem proteção ou expiração
API key identificar cliente/credencial simples tratar chave como autorização ilimitada
token de acesso representar autorização concedida registrar token ou aceitar audiência errada
mTLS autenticar pares por certificados supor que identidade técnica substitui regra de negócio
papel/escopo/política decidir autorização checar rota, mas não o objeto solicitado

OAuth 2.0 e OpenID Connect

OAuth 2.0 é um framework de autorização que permite a um cliente obter acesso limitado a um recurso em nome de alguém ou de si próprio [20]. Não é, sozinho, um protocolo de autenticação do usuário. OpenID Connect adiciona uma camada de identidade sobre OAuth 2.0.

A terminologia básica inclui:

  • resource owner;
  • client;
  • authorization server;
  • resource server;
  • access token e, em alguns fluxos, refresh token.

Para aplicações modernas, práticas históricas inseguras não devem ser copiadas de exemplos antigos. A RFC 9700 consolida recomendações atuais de segurança para OAuth 2.0, incluindo proteção contra redirecionamentos e roubo de tokens [21]. A escolha do fluxo depende do tipo de cliente e do provedor; tokens precisam de audiência, escopo, expiração e armazenamento adequados.

8.8 Segurança de API: controle por objeto

O OWASP API Security Top 10 de 2023 destaca falhas como autorização quebrada no nível de objeto, autenticação quebrada, consumo irrestrito de recursos e inventário inadequado [22].

Exemplo de BOLA — Broken Object Level Authorization:

GET /api/v1/tickets/420

O usuário troca 420 por 421 e recebe um chamado alheio. A rota exigia login, mas não verificava permissão sobre o objeto. IDs imprevisíveis dificultam enumeração, porém não substituem autorização.

Controles mínimos incluem:

  • negar por padrão;
  • validar autorização em cada objeto e propriedade sensível;
  • limitar tamanho, taxa e custo de consultas;
  • usar queries parametrizadas;
  • separar credenciais por integração;
  • manter inventário e desativar versões antigas;
  • reduzir dados na resposta;
  • registrar decisões relevantes sem expor segredos.

CORS não é controle de autorização da API

CORS informa a navegadores quais origens podem ler respostas em certos cenários [33]. Clientes fora do navegador, servidores e ferramentas HTTP não são impedidos por essa política. Configurar CORS corretamente protege a interação do navegador, mas a API ainda precisa autenticar e autorizar cada chamada.

8.9 Timeouts, retentativas e idempotência

Sem timeout, uma dependência lenta pode consumir todas as threads ou conexões do chamador. Com retentativa agressiva, a mesma lentidão pode virar uma tempestade.

Uma política madura especifica:

  • timeout de conexão e de resposta;
  • orçamento total da operação;
  • quais erros são transitórios;
  • número máximo de tentativas;
  • backoff exponencial e jitter;
  • respeito a Retry-After quando aplicável;
  • idempotência e deduplicação;
  • destino de falhas permanentes.

Exemplo de intervalos aproximados com jitter: 1 s, 2 s, 4 s, limitados a três novas tentativas. Isso não é uma receita universal; a soma deve caber no prazo do usuário e na capacidade da dependência.

Idempotency key

Para criação que não é naturalmente idempotente, o cliente envia uma chave única. O servidor associa chave, identidade, operação e hash do conteúdo ao resultado. Se a mesma chave e o mesmo conteúdo reaparecem, devolve o resultado armazenado; se o conteúdo muda, responde conflito.

chave nova + conteúdo A   → cria ticket 9821
mesma chave + conteúdo A  → devolve ticket 9821
mesma chave + conteúdo B  → 409 Conflict

Guardar apenas a chave sem escopo, expiração e vínculo ao payload permite colisões perigosas.

8.10 Consistência e falhas parciais

Uma integração distribuída raramente possui uma transação única que abrange GLPI, Slack, IA e e-mail. Considere:

  1. o GLPI cria o chamado;
  2. o fluxo solicita classificação à IA;
  3. atualiza o GLPI;
  4. envia mensagem ao Slack.

Se o passo 4 falha, desfazer a criação do chamado provavelmente seria pior. O sistema deve registrar estados independentes e retomar apenas o passo pendente. Padrões como outbox transacional, fila durável e consumidor idempotente ajudam a conectar alteração local e publicação de evento [35].

“Exatamente uma vez” de ponta a ponta é uma promessa muito forte. Na prática, sistemas costumam combinar entrega pelo menos uma vez com deduplicação e efeitos idempotentes.

8.11 Versionamento e evolução compatível

Versionar não é apenas inserir /v1 na URL. A evolução pode ocorrer por caminho, header, media type ou nova operação. O importante é classificar mudanças:

  • geralmente compatível: adicionar campo opcional que clientes toleram;
  • potencialmente incompatível: tornar campo obrigatório, mudar tipo, remover valor de enumeração, alterar semântica;
  • operacional: reduzir limite, alterar paginação ou expiração, mesmo sem mudar schema.

Boas práticas:

  1. publicar política de compatibilidade;
  2. medir quais versões são usadas;
  3. anunciar depreciação e data de desligamento;
  4. oferecer ambiente e testes de migração;
  5. manter contrato legível por máquina;
  6. validar consumidores críticos antes de remover comportamento.

Clientes robustos ignoram campos desconhecidos quando o contrato permite e não dependem da ordem de propriedades JSON.

8.12 Observabilidade de integrações

Uma operação deve ser rastreável sem juntar logs manualmente por tentativa. Propague identificadores e registre transições de estado.

Campos úteis:

{
  "timestamp": "2026-08-28T12:15:03Z",
  "level": "ERROR",
  "service": "ticket-classifier",
  "operation": "update_glpi_ticket",
  "request_id": "req-7f9c",
  "event_id": "evt-a311",
  "ticket_id": 9821,
  "attempt": 3,
  "duration_ms": 2010,
  "result": "timeout",
  "dependency": "glpi-api"
}

Não inclua o token, a descrição confidencial do chamado nem o prompt completo se contiver dados pessoais. Métricas complementares: taxa de sucesso, latência p50/p95/p99, tamanho da fila, idade do item mais antigo, tentativas e itens na fila de falhas.

8.13 Exemplo corporativo: GLPI, n8n, Slack e IA

Objetivo

Ao criar um chamado, classificá-lo de forma assistida, sugerir prioridade, avisar a equipe e preservar decisão humana.

Fluxo proposto

  1. GLPI registra o chamado como sistema de origem.
  2. Um evento ou polling incremental entrega apenas o identificador ao n8n.
  3. O fluxo recupera os campos necessários por API com credencial de mínimo privilégio.
  4. Dados sensíveis são removidos ou mascarados antes da IA.
  5. O modelo retorna categoria sugerida, confiança e justificativa estruturada.
  6. Regras determinísticas validam valores permitidos.
  7. Se a confiança estiver abaixo do limiar, o chamado vai para revisão humana.
  8. A atualização do GLPI usa controle de versão ou verifica o estado atual para não sobrescrever edição do técnico.
  9. A notificação ao Slack é enviada de forma independente e idempotente.
  10. Decisão, modelo, versão de prompt e resultado são auditados.

Comparação de desenhos

Desenho Benefício Falha predominante
chamada síncrona à IA antes de criar ticket classificação imediata IA indisponível impede o processo principal
criar ticket e classificar depois função principal resiliente consistência eventual visível por alguns segundos
IA altera prioridade sem revisão automação máxima erro pode afetar SLA e atendimento
IA sugere e regra/humano confirma controle e auditabilidade maior esforço operacional

Para um fluxo de suporte, a segunda e a quarta opções costumam produzir uma fronteira de risco melhor: o chamado nunca depende da IA para existir, e decisões de impacto alto permanecem controladas.

Exemplo de saída estruturada da IA

{
  "suggested_category": "Acesso > ERP",
  "suggested_priority": 3,
  "confidence": 0.86,
  "rationale": "Relato indica credencial válida com autorização recusada",
  "requires_human_review": false
}

O schema é validado; a categoria é conferida contra o catálogo; e prioridade não é aceita apenas porque o JSON está bem formado.

8.14 Síntese do capítulo

  • API é contrato de capacidade, dados, erros e operação.
  • REST é um estilo com restrições; JSON e CRUD não bastam para defini-lo.
  • Síncrono e assíncrono possuem acoplamentos e falhas diferentes.
  • OAuth 2.0 trata de autorização; OpenID Connect adiciona identidade.
  • CORS não substitui autenticação nem autorização.
  • Retentativas exigem timeout, backoff, limite e idempotência.
  • Em integrações distribuídas, falhas parciais são estados a tratar, não exceções raras.

Notas Zettelkasten — Capítulo 8

ZK-031 — Contrato de API
Ideia: uma API define semântica, dados, erros, identidade, limites e evolução;
o endpoint é apenas seu ponto de acesso.
Conexões: ZK-030 — Semântica HTTP; ZK-032 — Integração resiliente.

ZK-032 — Integração resiliente
Ideia: timeouts limitam espera; filas desacoplam tempo; idempotência contém
duplicatas; observabilidade torna falhas parciais reconstruíveis.
Conexões: ZK-025 — Processo e serviço; ZK-034 — Transação e consistência.

Recuperação ativa — Capítulo 8

  1. Por que uma API com JSON e URLs de recursos pode não cumprir REST integralmente?
  2. Quando o processamento assíncrono é melhor que a resposta imediata?
  3. Qual é a diferença entre webhook e fila durável?
  4. Por que OAuth 2.0 não deve ser apresentado como autenticação?
  5. Como uma idempotency key evita duas criações?
  6. Por que CORS não impede um script de servidor de chamar a API?
  7. O que deve acontecer se o Slack falhar depois que o ticket foi criado?

Capítulo 9 — Banco de Dados: Introdução Prática

Objetivos de aprendizagem

Ao final deste capítulo, você deverá conseguir:

  • distinguir banco de dados, SGBD, schema e aplicação;
  • modelar entidade, atributo, chave e relacionamento;
  • explicar integridade e normalização com seus trade-offs;
  • escrever consultas básicas e interpretar JOIN;
  • reconhecer duplicação causada por cardinalidade;
  • explicar transação, ACID e níveis de isolamento;
  • avaliar quando um índice ajuda ou prejudica;
  • separar backup, réplica, snapshot e restauração;
  • consultar o modelo do GLPI com segurança analítica.

9.1 Banco de dados e SGBD

Um banco de dados é uma coleção organizada de dados relacionados. Um Sistema Gerenciador de Banco de Dados oferece mecanismos para definir, consultar, alterar, proteger, recuperar e coordenar esse conjunto. PostgreSQL, MySQL, MariaDB, SQL Server e Oracle Database são SGBDs; o conjunto de chamados do GLPI é o banco gerenciado por um deles.

O schema descreve estruturas, tipos, chaves, restrições e relações. A aplicação implementa regras e experiências de uso. Confundir os três leva a erros como alterar diretamente uma tabela do GLPI sem conhecer invariantes mantidos pela aplicação.

Por que não usar apenas planilhas ou arquivos?

Arquivos CSV são excelentes para intercâmbio e análise pontual. Tornam-se frágeis quando múltiplas pessoas alteram dados relacionados, quando é necessária integridade entre registros ou quando uma falha não pode deixar metade da operação gravada.

Necessidade Arquivo/planilha SGBD relacional
edição concorrente coordenação externa controle de concorrência
relação entre conjuntos convenção manual chaves e JOIN
restrição de domínio validação frágil tipos, CHECK, UNIQUE, FK
alteração atômica difícil transação
consulta flexível exige processamento adicional SQL e otimizador
recuperação cópia do arquivo estratégias lógicas, físicas e contínuas

Um SGBD não garante qualidade automaticamente. Sem constraints e transações bem projetadas, ele preservará dados inconsistentes com grande eficiência.

9.2 Tabela, linha, coluna e domínio

No modelo relacional, uma relação possui atributos e tuplas; produtos SQL materializam conceitos próximos como tabelas, colunas e linhas. A correspondência não é perfeita: SQL admite NULL, duplicatas em resultados e detalhes físicos que não pertencem ao modelo matemático.

Exemplo simplificado:

CREATE TABLE categories (
    id          BIGINT PRIMARY KEY,
    name        VARCHAR(120) NOT NULL UNIQUE
);

CREATE TABLE tickets (
    id          BIGINT PRIMARY KEY,
    title       VARCHAR(255) NOT NULL,
    status      VARCHAR(20) NOT NULL,
    category_id BIGINT,
    opened_at   TIMESTAMP NOT NULL,
    CONSTRAINT fk_ticket_category
        FOREIGN KEY (category_id) REFERENCES categories(id),
    CONSTRAINT ck_ticket_status
        CHECK (status IN ('new', 'assigned', 'pending', 'solved', 'closed'))
);

O tipo limita representação; NOT NULL exige presença; UNIQUE evita repetição segundo a semântica do SGBD; a chave estrangeira preserva referência; CHECK expressa domínio permitido.

NULL não é zero nem texto vazio

NULL representa ausência ou desconhecimento conforme a modelagem. Comparações usam lógica de três valores:

-- Incorreto para procurar ausência
WHERE category_id = NULL

-- Correto
WHERE category_id IS NULL

Se NULL significa três coisas diferentes — “não informado”, “não se aplica” e “ainda não calculado” — o modelo provavelmente precisa de estados explícitos.

9.3 Chaves, integridade e cardinalidade

Uma chave primária identifica cada linha. Uma chave estrangeira referencia uma chave candidata de outra tabela e sustenta integridade referencial.

Cardinalidade descreve quantas ocorrências se relacionam:

  • uma categoria possui muitos tickets; cada ticket pode ter uma categoria;
  • um ticket possui vários atores; um usuário atua em vários tickets;
  • uma tabela associativa representa a relação muitos-para-muitos.

Modelo conceitual:

users 1 ──< tickets_users >── 1 tickets
                    │
                    └── type: solicitante, técnico ou observador

tickets_users não é ruído acidental. Ela registra a participação e o papel de cada usuário no ticket. Ignorar type ao fazer o JOIN transforma todos os atores em uma categoria indistinta.

Integridade no banco e regra na aplicação

Restrições próximas ao dado impedem estados impossíveis para todos os clientes. Regras contextuais complexas também podem existir na aplicação. O desenho não deve depender apenas da tela: importações, scripts e integrações podem contorná-la.

9.4 Normalização e desnormalização consciente

Normalização reduz redundância e anomalias. Se o nome da categoria for copiado para cada ticket, renomear a categoria exige atualizar milhares de linhas e pode deixar versões divergentes. Separar categories e referenciar category_id evita esse problema.

Uma leitura prática das primeiras formas normais:

  • 1FN: valores atômicos no contexto e estrutura tabular consistente;
  • 2FN: atributos não chave dependem da chave completa, relevante em chaves compostas;
  • 3FN: atributos não chave não dependem transitivamente de outro atributo não chave.

Exemplo problemático:

ticket_id | category_id | category_name | technician_id | technician_email

category_name depende de category_id; technician_email, de technician_id. A linha mistura fatos sobre ticket, categoria e usuário.

Normalizar não é maximizar o número de tabelas

Desnormalização pode ser deliberada em leitura analítica, cache ou snapshot histórico. Um data warehouse pode armazenar dimensão e fatos de forma otimizada para relatório. A decisão deve registrar:

  • qual consulta é beneficiada;
  • qual redundância é criada;
  • quem mantém consistência;
  • qual atraso é aceitável;
  • como reconstruir o derivado.

9.5 Consultas SQL: intenção e ordem lógica

Uma consulta simples:

SELECT id, title, status, opened_at
FROM tickets
WHERE status IN ('new', 'assigned')
  AND opened_at >= :start_at
  AND opened_at < :end_at
ORDER BY opened_at DESC
LIMIT 100;

O intervalo semiaberto (>= início e < próximo início) evita depender de 23:59:59.999... e funciona melhor com precisão variável. Parâmetros separam valores do texto SQL e ajudam a prevenir injeção.

A ordem escrita não é a ordem conceitual completa. De forma simplificada, o SGBD forma as fontes e junções, filtra, agrupa, aplica condições de grupo, projeta, remove duplicatas, ordena e limita. O otimizador pode executar fisicamente de outra maneira preservando o resultado.

Seleção explícita

Em integração e relatório durável, evite SELECT *:

  • transfere colunas desnecessárias;
  • pode expor dado sensível recém-adicionado;
  • deixa o contrato frágil a mudanças;
  • dificulta identificar origem em joins.

9.6 JOIN: combinar relações sem perder cardinalidade

Considere:

tickets                      categories
+----+-------------+         +----+-------------+
| id | category_id |         | id | name        |
+----+-------------+         +----+-------------+
| 10 | 3           |         | 3  | Redes       |
| 11 | NULL        |         | 4  | Aplicações  |
+----+-------------+         +----+-------------+

INNER JOIN mantém apenas correspondências:

SELECT t.id, c.name
FROM tickets AS t
JOIN categories AS c ON c.id = t.category_id;

LEFT JOIN preserva todos os tickets e preenche categoria com NULL quando ausente:

SELECT t.id, c.name
FROM tickets AS t
LEFT JOIN categories AS c ON c.id = t.category_id;

O local do filtro muda o resultado

-- Preserva tickets sem categoria ativa
LEFT JOIN categories AS c
  ON c.id = t.category_id
 AND c.active = 1
``````sql
-- O WHERE elimina linhas em que c é NULL; na prática, aproxima-se de INNER JOIN
LEFT JOIN categories AS c ON c.id = t.category_id
WHERE c.active = 1

Não mova condições entre ON e WHERE como simples formatação.

Multiplicação de linhas

Se um ticket tem dois solicitantes e três técnicos, juntar as duas relações diretamente pode produzir seis combinações. DISTINCT pode esconder o sintoma e ainda retornar dados incorretos. Agregue cada relação à granularidade de um ticket antes de combiná-las.

9.7 Agregação e granularidade

Antes de escrever GROUP BY, defina o que uma linha do resultado representa:

  • um ticket;
  • um técnico por mês;
  • uma categoria por dia;
  • um evento do histórico.

Exemplo: quantidade de tickets por categoria no período:

SELECT
    c.name AS category,
    COUNT(*) AS ticket_count
FROM tickets AS t
LEFT JOIN categories AS c ON c.id = t.category_id
WHERE t.opened_at >= :start_at
  AND t.opened_at < :end_at
GROUP BY c.id, c.name
ORDER BY ticket_count DESC;

COUNT(*) conta linhas. COUNT(c.id) ignora NULL. A escolha muda a resposta para tickets sem categoria.

Uma média também pode enganar: tempo médio de resolução esconde cauda longa. Indicadores operacionais devem considerar percentis, volume, backlog e definição exata do relógio de SLA.

9.8 Transações e ACID

Uma transação agrupa operações que precisam ser confirmadas ou desfeitas como unidade. As propriedades ACID são [25]:

  • Atomicidade: todos os efeitos da transação são confirmados ou nenhum;
  • Consistência: a transação leva o banco de um estado que satisfaz as regras codificadas a outro;
  • Isolamento: transações concorrentes não devem observar interferência além do permitido pelo nível escolhido;
  • Durabilidade: após confirmação, o SGBD preserva o resultado diante das falhas cobertas por sua arquitetura.

Consistência não significa “o dado corresponde ao mundo real”. Se a aplicação grava prioridade errada dentro de uma transação válida, ACID não descobre o erro de negócio. A propriedade depende de constraints e invariantes efetivamente expressos.

Exemplo: transferência de responsabilidade

BEGIN;

UPDATE tickets
SET technician_id = :new_technician
WHERE id = :ticket_id;

INSERT INTO ticket_history(ticket_id, event_type, actor_id, occurred_at)
VALUES (:ticket_id, 'technician_changed', :actor_id, CURRENT_TIMESTAMP);

COMMIT;

Se o histórico falha e o vínculo é confirmado mesmo assim, auditoria e estado divergem. A transação local resolve essa atomicidade; não inclui automaticamente o Slack ou outro serviço.

9.9 Isolamento e anomalias

Concorrência cria situações que não aparecem em testes com um usuário:

  • dirty read: ler mudança ainda não confirmada;
  • nonrepeatable read: reler a mesma linha e obter valor confirmado diferente;
  • phantom: repetir uma condição e encontrar conjunto diferente;
  • lost update: uma gravação sobrescreve outra sem detectar conflito;
  • write skew: transações preservam verificações individuais, mas violam invariante conjunto.

SGBDs implementam níveis de isolamento com diferenças relevantes. A documentação atual do PostgreSQL, por exemplo, explica que Read Uncommitted é tratado como Read Committed e que Serializable pode abortar transações que precisam ser repetidas [24]. MySQL/InnoDB possui seus próprios padrões e mecanismos.

Maior isolamento reduz algumas anomalias, mas pode aumentar conflitos, bloqueios ou abortos. A aplicação deve:

  1. escolher o nível pelo invariante;
  2. manter transações curtas;
  3. acessar recursos em ordem consistente;
  4. tratar deadlocks e falhas de serialização com retentativa limitada;
  5. não manter transação aberta enquanto aguarda interação humana ou API remota.

9.10 Índices e planos de execução

Um índice é uma estrutura auxiliar que acelera certos acessos ao custo de espaço e manutenção em escrita. InnoDB, por exemplo, organiza dados pelo índice clusterizado e armazena a chave primária nos índices secundários [28].

Quando um índice ajuda

  • coluna ou conjunto usado para localizar pequena fração das linhas;
  • junção por chave;
  • ordenação compatível;
  • restrição de unicidade;
  • consulta coberta pelas colunas necessárias, conforme o SGBD.

Quando pode ajudar pouco

Um índice apenas em status pode ter baixa seletividade se quase todos os tickets estão fechados. Um índice composto como (status, opened_at) pode servir a uma consulta específica, mas a ordem importa e deve ser validada com dados reais.

EXPLAIN
SELECT id, title, opened_at
FROM tickets
WHERE status = 'open'
  AND opened_at >= :start_at
ORDER BY opened_at DESC
LIMIT 100;

Não conclua “está usando índice, então está rápido”. Leia estimativas, linhas examinadas, método de junção, ordenação e diferença para tempos reais. Estatísticas desatualizadas e distribuição desigual podem induzir planos ruins.

Custo de indexar tudo

Cada INSERT, UPDATE relevante e DELETE precisa manter índices. Muitos índices aumentam escrita, armazenamento, cache e tempo de manutenção. Índice é resposta a um padrão de acesso medido, não decoração de schema.

9.11 Backup, réplica, snapshot, RPO e RTO

Backup é uma cópia recuperável, preservada segundo política, usada para restaurar dados após perda ou corrupção. Réplica mantém uma cópia atualizada para disponibilidade ou leitura; pode replicar exclusão acidental. Snapshot captura o estado de um volume ou sistema em um instante, mas sua consistência e independência dependem da tecnologia. Nenhum deles é automaticamente equivalente aos demais.

O PostgreSQL documenta três famílias amplas: dump SQL, backup de sistema de arquivos e arquivamento contínuo [26]. Arquivamento de log com base backup permite recuperação para um ponto no tempo — PITR — dentro do período preservado [27]. Outros SGBDs possuem mecanismos próprios.

RPO e RTO

  • RPO — Recovery Point Objective: perda máxima de dados tolerável medida no tempo;
  • RTO — Recovery Time Objective: tempo alvo para restabelecer o serviço.

Se o último backup recuperável é de meia-noite e a falha ocorre às 16h, a perda potencial é 16 horas. Ter backup diário não produz RPO de cinco minutos.

Uma política completa define:

  • escopo e frequência;
  • retenção e cópia fora do domínio de falha;
  • criptografia e controle de acesso;
  • consistência da aplicação;
  • catálogo e monitoramento;
  • teste periódico de restauração;
  • sequência de recuperação de dependências.

Backup não testado é uma hipótese. O teste deve medir tempo, validar integridade e confirmar que a aplicação realmente inicia com o dado restaurado.

9.12 Banco, API e BI: fronteiras seguras

Ferramentas de BI podem consultar uma réplica ou camada analítica. Integrações operacionais devem preferir APIs quando a aplicação precisa preservar regras, permissões, histórico e compatibilidade.

Acesso Vantagem Risco Uso indicado
API oficial preserva contrato e regras limites e menor flexibilidade criar/alterar entidades
leitura SQL em réplica consulta flexível e eficiente acoplamento ao schema interno relatórios controlados
escrita direta no banco da aplicação aparente rapidez viola invariantes, suporte e auditoria evitar, salvo procedimento oficial explícito
data warehouse estabilidade analítica defasagem e pipeline adicional histórico, indicadores e cruzamentos

No GLPI, o modelo de banco é interno à aplicação e pode evoluir; a documentação de desenvolvimento apresenta convenções e ressalta estruturas específicas [29]. A API oficial é a fronteira mais estável para automação suportada [31]. Para relatórios SQL, use conta somente leitura, réplica quando disponível, inventário de versão e testes após atualização.

9.13 Consulta GLPI: atores sem duplicação indevida

A consulta original associava glpi_tickets_users uma única vez e chamava qualquer usuário encontrado de técnico. No GLPI, atores possuem papéis distintos: solicitante, atribuído e observador [30]. Na tabela de associação, esses papéis são representados por type = 1, 2 e 3, respectivamente, conforme registros técnicos do projeto [36].

Uma primeira correção seria filtrar type = 2. Porém, se houver vários técnicos, ainda haverá mais de uma linha por ticket. E, se solicitantes e técnicos forem juntados simultaneamente, suas cardinalidades podem se multiplicar. A solução abaixo agrega cada papel antes do JOIN principal.

Escopo: exemplo de leitura para o schema do GLPI 10.0.15. Valide em homologação e no schema efetivamente instalado; extensões e atualizações podem alterar necessidades. Não use escrita SQL direta para modificar tickets.

SELECT
    t.id,
    t.name AS titulo,
    e.completename AS entidade,
    c.completename AS categoria,
    solicitantes.nomes AS solicitantes,
    tecnicos.nomes AS tecnicos,
    t.status,
    t.date AS abertura
FROM glpi_tickets AS t
LEFT JOIN glpi_entities AS e
       ON e.id = t.entities_id
LEFT JOIN glpi_itilcategories AS c
       ON c.id = t.itilcategories_id
LEFT JOIN (
    SELECT
        tu.tickets_id,
        GROUP_CONCAT(
            DISTINCT COALESCE(
                NULLIF(TRIM(CONCAT_WS(' ', u.firstname, u.realname)), ''),
                u.name
            )
            ORDER BY u.name
            SEPARATOR ', '
        ) AS nomes
    FROM glpi_tickets_users AS tu
    INNER JOIN glpi_users AS u
            ON u.id = tu.users_id
    WHERE tu.type = 1
    GROUP BY tu.tickets_id
) AS solicitantes
        ON solicitantes.tickets_id = t.id
LEFT JOIN (
    SELECT
        tu.tickets_id,
        GROUP_CONCAT(
            DISTINCT COALESCE(
                NULLIF(TRIM(CONCAT_WS(' ', u.firstname, u.realname)), ''),
                u.name
            )
            ORDER BY u.name
            SEPARATOR ', '
        ) AS nomes
    FROM glpi_tickets_users AS tu
    INNER JOIN glpi_users AS u
            ON u.id = tu.users_id
    WHERE tu.type = 2
    GROUP BY tu.tickets_id
) AS tecnicos
        ON tecnicos.tickets_id = t.id
WHERE t.is_deleted = 0
  AND t.date >= :inicio
  AND t.date < :fim
ORDER BY t.date DESC, t.id DESC;

Parâmetros para maio de 2026:

:inicio = 2026-05-01 00:00:00
:fim    = 2026-06-01 00:00:00

Por que essa versão é melhor?

  1. separa solicitante (type = 1) de técnico atribuído (type = 2);
  2. reduz cada conjunto de atores a uma linha por ticket antes de combinar;
  3. preserva tickets sem categoria ou técnico por meio de LEFT JOIN;
  4. exclui registros logicamente removidos;
  5. usa intervalo semiaberto, sem depender da precisão do último segundo;
  6. recebe datas por parâmetro;
  7. inclui id como segundo critério para ordenação determinística.

Limites do exemplo

  • GROUP_CONCAT possui limite de tamanho configurável e é específico da família MySQL/MariaDB;
  • nomes exibidos podem exigir política diferente de fallback;
  • o valor numérico de status deve ser traduzido pela camada de apresentação conforme a versão, não por texto SQL espalhado;
  • entidades filhas e permissões não são reproduzidas automaticamente por uma consulta direta;
  • o schema físico é contrato interno menos estável que a API.

Para uma linha por ator, remova a agregação e declare a granularidade como “ticket + papel + usuário”. Para BI histórico, extraia para um modelo analítico em vez de executar consultas pesadas repetidamente no banco transacional.

9.14 Síntese do capítulo

  • O SGBD oferece estruturas, integridade, concorrência e recuperação; não substitui modelagem.
  • NULL exige semântica explícita.
  • Chaves preservam identidade e relações; cardinalidade determina a forma do JOIN.
  • Normalização reduz anomalias; desnormalização deve ser controlada.
  • ACID preserva regras codificadas, não a verdade do negócio.
  • Níveis de isolamento controlam anomalias com custos distintos.
  • Índices atendem padrões de consulta e cobram manutenção.
  • Réplica e snapshot não substituem backup recuperável.
  • Escrita na aplicação deve passar pela API; SQL direto é apropriado apenas para leitura governada.

Notas Zettelkasten — Capítulo 9

ZK-033 — Cardinalidade antes do JOIN
Ideia: defina o que uma linha representa e agregue relações multivaloradas
antes de combiná-las; DISTINCT não corrige uma granularidade errada.
Conexões: ZK-031 — Contrato de API; ZK-034 — Transação e consistência.

ZK-034 — Transação e consistência
Ideia: ACID protege invariantes codificados no banco; integrações externas
exigem estados, compensação ou mensageria além da transação local.
Conexões: ZK-032 — Integração resiliente; ZK-035 — Recuperação verificável.

ZK-035 — Recuperação verificável
Ideia: backup só se torna evidência de recuperação quando restauração,
integridade, RPO e RTO são testados no contexto da aplicação.
Conexões: ZK-026 — Pressão de memória; ZK-034 — Transação e consistência.

Recuperação ativa — Capítulo 9

  1. Qual é a diferença entre banco de dados, SGBD, schema e aplicação?
  2. Por que NULL não deve ser comparado com =?
  3. Como um LEFT JOIN pode se comportar como INNER JOIN após um filtro?
  4. Por que dois solicitantes e três técnicos podem gerar seis linhas?
  5. O que a consistência de ACID não consegue garantir?
  6. Por que um índice de baixa seletividade pode ajudar pouco?
  7. Como réplica pode reproduzir uma exclusão acidental?
  8. Por que a consulta GLPI agrega atores antes do JOIN principal?

Estudo de caso integrado — Do clique ao relatório do GLPI

Contexto

A empresa Exemplo mantém o GLPI como sistema de chamados. Gestores acessam um portal de relatórios em https://suporte.exemplo.com/relatorios/. O portal não grava diretamente nas tabelas do GLPI: lê de uma réplica com credencial restrita. Criações e alterações usam a API oficial. Um fluxo n8n recebe eventos, solicita classificação assistida por IA e envia notificações ao Slack.

O objetivo do estudo não é recomendar produtos específicos, mas aplicar o raciocínio dos capítulos em uma única cadeia.

1. Componentes e responsabilidades

Componente Responsabilidade Estado que domina Evidência principal
navegador apresentar e iniciar operações sessão e cache do cliente DevTools e console
DNS recursivo/autoritativo resolver/publicar nomes cache e zona resposta, TTL e autoridade
firewall/roteamento permitir e encaminhar fluxos regras, rotas e sessões logs e tabelas
Nginx terminar TLS e encaminhar HTTP configuração de rotas/upstreams access/error log
portal de relatórios autenticar, autorizar e montar visão processo e configuração logs, métricas e traces
réplica GLPI atender consultas de leitura dados e atraso de replicação plano, locks e lag
API GLPI preservar regra em alterações domínio transacional status, corpo e log da aplicação
n8n orquestrar etapas execução do workflow histórico por execução
IA produzir sugestão estruturada modelo e contexto recebido versão, schema e avaliação
Slack entregar notificação mensagem/canal ID e resposta da API

Nenhum componente deve ser chamado de “fonte da verdade” sem qualificar para qual fato. O GLPI é fonte do estado do ticket; o provedor de identidade, da identidade; o workflow, do estado da automação; e o sistema de métricas, da observação operacional.

2. Arquitetura e fronteiras

flowchart TB
    U["Usuário"] -->|HTTPS| N["Nginx"]
    N -->|"/relatorios/"| P["Portal"]
    P --> R["Réplica GLPI"]
    N -->|"/glpi/"| G["Aplicação GLPI"]
    G --> B["Banco primário"]
    G -->|evento| W["n8n"]
    W --> I["IA"]
    W -->|API| G
    W --> S["Slack"]

Decisões de desenho:

  • o banco primário não é exposto ao navegador;
  • o portal recebe somente as colunas de que precisa;
  • consultas pesadas usam réplica e possuem timeout;
  • alterações passam pela API, não por UPDATE direto;
  • a criação do ticket não depende da IA nem do Slack;
  • cada evento possui event_id; cada operação, request_id;
  • segredos ficam fora do código e não aparecem em logs;
  • o proxy aceita tráfego público; banco e serviços internos aceitam apenas origens necessárias.

3. Caminho saudável de uma consulta

Etapa A — Nome e transporte

  1. O navegador pede A e/ou AAAA para suporte.exemplo.com.
  2. O resolvedor devolve o endereço público com TTL.
  3. O host seleciona rota e abre conexão.
  4. Cliente e proxy negociam TLS; o nome do certificado é validado.

Etapa B — HTTP e identidade

  1. O cliente envia GET /relatorios/tickets?period=2026-05.
  2. O Nginx encaminha para o upstream do portal e estabelece request_id.
  3. O portal valida sessão, identidade e permissão para ver a entidade solicitada.

Etapa C — Dados

  1. O portal converte period em parâmetros :inicio e :fim; não concatena SQL.
  2. A réplica escolhe um plano, executa a consulta e devolve linhas.
  3. O portal calcula a representação e limita dados ao papel do usuário.
  4. O proxy devolve status, headers de cache compatíveis e conteúdo.
  5. Logs, métricas e trace registram duração por etapa.

O tempo total pode ser modelado, de forma simplificada, como:

\[T_{total} = T_{DNS} + T_{conexão} + T_{TLS} + T_{proxy} + T_{aplicação} + T_{banco} + T_{retorno}\]

Algumas parcelas se sobrepõem ou desaparecem por cache e conexão reutilizada. Ainda assim, decompor o tempo impede culpar “a rede” por uma consulta que passa 4,8 segundos no banco.

4. Incidente A — 502 Bad Gateway após implantação

Sintoma

/glpi/ funciona, mas /relatorios/ devolve 502 para todos os usuários após uma implantação.

Evidências

DNS: suporte.exemplo.com → endereço esperado
TLS: certificado válido
Nginx access log: GET /relatorios/ 502
Nginx error log: connect() failed (111: Connection refused)
Upstream configurado: relatorios_app:5000
Aplicação: escutando em 0.0.0.0:8000

Raciocínio

  • DNS e TLS concluíram porque o Nginx respondeu.
  • 502 e connection refused localizam a falha entre proxy e upstream.
  • “Connection refused” sugere que o destino respondeu sem processo escutando naquela porta; difere de timeout silencioso.
  • O processo está saudável em outra porta. O contrato de implantação e a configuração do proxy divergiram.

Correção e prevenção

Alinhar a porta por configuração versionada, testar o caminho publicado e promover a mesma configuração validada. Um health check que consulta apenas :8000 não valida que o proxy aponta para ela; o teste deve atravessar a fronteira pública ou equivalente de homologação.

5. Incidente B — parte dos clientes abre o endereço antigo

Sintoma

Após migração, a equipe interna acessa o novo portal, mas um escritório continua vendo o antigo.

Evidências

Autoritativo: A = 203.0.113.20, TTL 300
Resolvedor do escritório: A = 203.0.113.10, TTL restante 1800
TTL anterior à mudança: 86400

Raciocínio

O servidor autoritativo foi alterado, mas o resolvedor ainda possui resposta criada com TTL antigo. Reduzir o TTL para 300 no momento da migração não modifica a validade da resposta já armazenada.

Correção e prevenção

Esperar expiração ou limpar cache controlado quando a política permitir. Em mudanças futuras, reduzir o TTL com antecedência superior ao TTL anterior, confirmar todos os servidores autoritativos e manter o destino antigo durante a janela planejada.

6. Incidente C — consulta lenta provoca tempestade de retentativas

Sintoma

O portal alterna entre 504 e 200; conexões do banco sobem rapidamente.

Evidências

Consulta sem limite: 7,8 s
Timeout do proxy: 5 s
Cliente do portal: 3 tentativas imediatas
Índice: apenas status
Filtro: status + intervalo de data; ordenação por data

Raciocínio

Cada solicitação lenta é abandonada pelo proxy aos 5 segundos, mas pode continuar consumindo recurso internamente. O cliente gera três consultas adicionais sem backoff. Baixa seletividade de status limita o índice atual; o plano e a distribuição precisam ser medidos.

Intervenção

  1. limitar e paginar a consulta;
  2. inspecionar plano com parâmetros representativos;
  3. avaliar índice composto compatível, medindo custo de escrita;
  4. cancelar trabalho quando o chamador abandona, se a pilha permitir;
  5. impedir retentativa automática para uma consulta pesada sem orçamento;
  6. proteger o banco com pool e limite de concorrência;
  7. medir p95/p99 e linhas examinadas.

Aumentar o timeout para 60 segundos pode esconder o sintoma e ampliar ocupação de recursos.

7. Incidente D — relatório conta o mesmo ticket seis vezes

Sintoma

O GLPI mostra um ticket, mas o relatório mostra seis linhas.

Dados

Ticket 9821
Solicitantes: Ana, Bruno
Técnicos: Carla, Diego, Elisa

Consulta defeituosa

FROM glpi_tickets AS t
JOIN glpi_tickets_users AS req ON req.tickets_id = t.id AND req.type = 1
JOIN glpi_tickets_users AS tech ON tech.tickets_id = t.id AND tech.type = 2

Raciocínio

Cada solicitante combina com cada técnico: 2 × 3 = 6. O banco executou corretamente o que foi pedido. O erro está na granularidade implícita.

Correção

Agregue solicitantes e técnicos separadamente por tickets_id, como na seção 9.13, ou devolva uma linha por ator com papel explícito. Não aplique DISTINCT sem compreender quais combinações serão descartadas.

8. Incidente E — notificação duplicada e prioridade divergente

Sintoma

Um ticket foi criado uma vez, recebeu duas mensagens no Slack e teve a prioridade manual sobrescrita pela IA.

Linha do tempo

10:00:00 evento evt-91 entregue ao n8n
10:00:02 IA sugere prioridade 3
10:00:03 técnico altera prioridade para 1
10:00:04 n8n grava prioridade 3 sem verificar versão
10:00:05 Slack aceita mensagem, mas resposta se perde
10:00:10 n8n repete todo o fluxo e envia segunda mensagem

Causas

  • entrega pelo menos uma vez foi tratada como exatamente uma vez;
  • não havia registro de etapa concluída por event_id;
  • atualização não verificou o estado lido ou versão do ticket;
  • a retentativa reexecutou efeitos já aceitos.

Redesenho

  • persistir estado por evento e etapa;
  • usar chave idempotente/identificador externo na notificação quando suportado;
  • separar “sugestão da IA” de “decisão aplicada”;
  • aplicar controle otimista: atualizar somente se a versão/estado ainda for o observado;
  • encaminhar conflito para revisão humana;
  • retentar apenas a etapa pendente.

9. Critérios de aceite e operação

Arquitetura se torna verificável quando possui critérios:

  • 99% das consultas de relatório respondem abaixo de 2 segundos para intervalos de até 31 dias;
  • nenhuma consulta do portal possui permissão de escrita no banco;
  • 100% das alterações de ticket usam API e identidade rastreável;
  • todo evento repetido produz no máximo um efeito lógico por destino;
  • falha da IA ou Slack não impede criação do ticket;
  • restore trimestral comprova o RTO definido e a consistência da aplicação;
  • atualização do GLPI executa teste de compatibilidade das consultas antes da promoção;
  • logs correlacionáveis não contêm tokens nem descrições confidenciais.

Esses números são exemplos. Metas reais precisam nascer do impacto de negócio e da capacidade medida.


Laboratório prático orientado

Objetivo

Diagnosticar uma aplicação Web por camadas, produzir evidências e evitar alterações destrutivas. O laboratório pode ser adaptado a Linux, Windows, container ou VM. Use apenas sistemas para os quais você possui autorização.

Cenário

O portal https://suporte.exemplo.com/relatorios/ está lento. O usuário relata “erro de rede”, mas nenhuma causa foi confirmada.

Etapa 1 — Escreva hipóteses antes dos comandos

Preencha:

Hipótese Evidência que a sustentaria Evidência que a enfraqueceria
DNS aponta para IP incorreto resposta difere do autoritativo esperado todos os resolvers devolvem destino correto
porta 443 bloqueada timeout TCP consistente handshake TCP concluído
certificado inválido falha de cadeia/nome/período validação TLS concluída
upstream lento proxy responde 504; trace concentra tempo no upstream upstream local rápido
banco lento duração da query e locks elevados consulta rápida e pool disponível

O quadro impede que cada novo dado gere uma conclusão improvisada.

Etapa 2 — Cliente e DNS

Linux:

date -Is
dig suporte.exemplo.com A
dig suporte.exemplo.com AAAA
curl -sS -o /dev/null -D - \
  -w 'remote_ip=%{remote_ip} code=%{http_code} connect=%{time_connect} tls=%{time_appconnect} total=%{time_total}\n' \
  https://suporte.exemplo.com/relatorios/

Windows PowerShell:

Get-Date -Format o
Resolve-DnsName suporte.exemplo.com
Test-NetConnection suporte.exemplo.com -Port 443
curl.exe -sS -o NUL -D - https://suporte.exemplo.com/relatorios/

Registre o resolvedor usado, endereços devolvidos, família escolhida, status e tempos. Não copie tokens para o relatório.

Etapa 3 — TLS e HTTP

curl -v --connect-timeout 5 --max-time 15 \
  https://suporte.exemplo.com/relatorios/
```Perguntas:
1. a conexão abriu?
2. qual protocolo foi negociado?
3. o nome do certificado corresponde?
4. houve redirecionamento?
5. qual servidor/intermediário gerou o status?
6. existe `request_id` para correlação?

Se precisar testar um IP sem alterar DNS, preserve o nome para SNI e `Host`:
```bash
curl --resolve suporte.exemplo.com:443:203.0.113.20 \
  https://suporte.exemplo.com/relatorios/

Substitua o endereço documental pelo destino autorizado. A opção isola DNS sem desativar validação TLS.

Etapa 4 — Proxy e aplicação

No servidor autorizado:

ss -lntp
systemctl status relatorios
journalctl -u relatorios --since "30 minutes ago"
curl -sS -D - -o /dev/null --max-time 5 http://127.0.0.1:8000/health
```Compare:
- porta configurada no proxy e porta de escuta;
- endpoint de vida e endpoint de prontidão;
- identidade do processo e acesso a arquivos;
- duração local e duração pelo proxy;
- limites do container e recursos do host.

Um endpoint de vida pode responder enquanto o banco está indisponível. Prontidão deve medir apenas dependências essenciais, com custo e timeout controlados; não transforme health check em consulta pesada.

## Etapa 5 — Banco de dados

Trabalhe com conta somente leitura e ferramentas aprovadas.
```sql
EXPLAIN
SELECT t.id, t.name, t.date
FROM glpi_tickets AS t
WHERE t.is_deleted = 0
  AND t.date >= :inicio
  AND t.date < :fim
ORDER BY t.date DESC
LIMIT 100;
```Observe:
- estimativa de linhas;
- índice escolhido;
- filtragem e ordenação;
- diferença entre período curto e longo;
- concorrência e pool;
- atraso da réplica.

Não crie índice em produção como experimento improvisado. Gere proposta, teste com volume representativo, meça impacto em leitura e escrita, planeje reversão.

## Etapa 6 — Correlação

Monte uma linha do tempo em UTC:

| Instante | Componente | `request_id` | Evento | Duração/resultado |
|---|---|---|---|---|
| 12:10:00.000 | Nginx | `req-71` | requisição recebida | — |
| 12:10:00.006 | portal | `req-71` | autenticação concluída | 4 ms |
| 12:10:00.012 | portal | `req-71` | consulta iniciada | — |
| 12:10:05.012 | Nginx | `req-71` | upstream timeout | 504 |
| 12:10:07.800 | banco | `req-71` | consulta concluída | 7.788 ms |

A linha mostra que o trabalho continuou após o proxy desistir. A correção deve abordar consulta, cancelamento e orçamento, não apenas “aumentar timeout”.

## Etapa 7 — Relatório de incidente

Use esta estrutura:
```text
Impacto:
Início e fim:
Ambientes e usuários afetados:

Sintoma observável:
Resultado esperado:

Hipóteses avaliadas:
Evidências:
Causa técnica:
Fatores contribuintes:

Contenção:
Correção definitiva:
Validação:

Ações preventivas, responsáveis e prazos:
Riscos residuais:

Separe causa de fator contribuinte. Uma consulta sem índice pode ser a causa imediata; ausência de teste de carga e retentativa agressiva podem ampliar o impacto.


Exercícios de fixação

Bloco A — Conceitos e comparações

  1. Um processo usa 100% de um núcleo, mas o servidor mostra 12,5% de CPU total. Explique.
  2. Compare processo, serviço, container e VM em quatro linhas.
  3. Por que “memória 95% usada” não basta para declarar vazamento?
  4. Dê um exemplo de concorrência sem paralelismo e um de condição de corrida.
  5. Explique por que uma VLAN sem política inter-VLAN não garante isolamento.
  6. Compare TCP, UDP e QUIC quanto a unidade, garantias e uso.
  7. O que ping, teste TCP, handshake TLS e GET /health provam separadamente?
  8. Por que alterar DNS e desligar imediatamente o destino antigo é arriscado?
  9. Diferencie método HTTP seguro de idempotente.
  10. Explique por que HTTPS não impede BOLA.

Bloco B — Análise aplicada

  1. O cliente recebe 401. Liste três hipóteses e uma evidência para cada.
  2. O cliente recebe 403 somente para /tickets/42. Qual camada investigar primeiro?
  3. O proxy responde 504, mas a aplicação conclui a operação depois. Qual risco surge se o cliente repetir POST?
  4. Um webhook é entregue três vezes. Proponha schema mínimo para deduplicação.
  5. O Slack está indisponível. Em qual desenho isso não deve impedir criação de tickets?
  6. Uma API devolve 200 com {"success": false}. Que problema contratual isso cria?
  7. Um token OAuth válido é aceito por API diferente da audiência pretendida. Qual validação faltou?
  8. O navegador bloqueia CORS. Isso prova que a API recusaria um cliente servidor-a-servidor? Justifique.
  9. Uma API retorna todos os campos do usuário porque “o frontend esconde os sensíveis”. Identifique o erro.
  10. Compare versionamento no caminho e evolução compatível sem nova versão.

Bloco C — Banco de dados e diagnóstico

  1. Qual resultado muda ao mover c.active = 1 do ON de um LEFT JOIN para WHERE?
  2. Um ticket possui dois observadores e quatro técnicos. Quantas linhas uma junção ingênua pode gerar?
  3. Por que DISTINCT não é a primeira solução para o exercício anterior?
  4. Explique atomicidade com um ticket e seu histórico.
  5. Dê um exemplo de lost update no campo de prioridade.
  6. Por que transação não deve permanecer aberta durante chamada à IA?
  7. Um índice em status tem apenas cinco valores em dez milhões de linhas. Por que pode ter baixa utilidade?
  8. Explique a diferença entre réplica, backup e PITR.
  9. Proponha RPO e RTO para um sistema e relacione-os a mecanismos técnicos.
  10. Na consulta GLPI, por que solicitantes e técnicos são agregados em subconsultas separadas?

Bloco D — Projeto

  1. Desenhe o fluxo de abertura de ticket com classificação assíncrona e revisão humana.
  2. Defina cinco campos de log e três métricas para o fluxo.
  3. Escreva um contrato de erro para categoria inválida.
  4. Proponha uma política de retentativas que respeite um orçamento total de 10 segundos.
  5. Crie uma matriz de comunicação mínima entre navegador, proxy, aplicação e banco.
  6. Escreva critérios de aceite para restauração de um backup.

Direções de resposta

  1. A média divide o uso entre oito núcleos; um fluxo pode saturar apenas um.
  2. Processo é execução; serviço é ciclo de vida; container isola processo compartilhando kernel; VM executa kernel convidado.
  3. Compare disponível, cache, RSS, faults, swap ativa, limites e tendência.
  4. Alternância em um núcleo é concorrência; leitura e gravação sem coordenação podem perder atualização.
  5. VLAN separa domínio L2; roteamento e firewall decidem a travessia.
  6. Retome a tabela da seção 6.7; evite usar apenas “velocidade”.
  7. Cada teste sobe uma promessa: ICMP, transporte, identidade/canal e aplicação.
  8. Caches ainda válidos podem apontar para o destino anterior.
  9. Seguro não solicita mudança; idempotente preserva efeito pretendido sob repetição.
  10. TLS protege o canal; autorização por objeto continua responsabilidade da API.
  11. Credencial ausente, expirada ou destinada a outro recurso; examine header, expiração e audiência sem expor o token.
  12. Autorização no nível do objeto, preservando a possibilidade de 404 deliberado.
  13. Duplicar o efeito; use idempotency key, estado e timeout coerente.
  14. event_id, origem, tipo, instante, hash/payload, status e resultado por etapa.
  15. Persistir ticket primeiro e processar notificação em etapa assíncrona independente.
  16. Intermediários, métricas e clientes interpretam sucesso quando houve erro.
  17. Validação de aud/destinatário e política do resource server.
  18. Não; CORS é aplicado pelo navegador, não autentica nem autoriza a API.
  19. Ocultar na interface não impede transferência; a API deve aplicar minimização e autorização por propriedade.
  20. /v1 torna ruptura explícita; adições compatíveis podem evoluir sob a mesma versão se o contrato permitir.
  21. O WHERE elimina NULL e remove linhas sem categoria ativa.
  22. Oito combinações.
  23. A granularidade permanece errada e valores diferentes podem impedir a deduplicação.
  24. Vínculo e histórico confirmam juntos ou são desfeitos juntos.
  25. IA lê prioridade 3, técnico grava 1, IA grava 2 com base em estado antigo.
  26. Aumenta locks e acopla recurso local à latência/falha externa.
  27. Baixa seletividade pode exigir muitas linhas; índice composto e plano devem ser medidos.
  28. Réplica acompanha mudanças; backup preserva cópia recuperável; PITR reproduz log até um ponto.
  29. A resposta depende do impacto; mostre como frequência, arquivamento e procedimento atendem aos tempos.
  30. Para evitar o produto cartesiano entre relações multivaloradas.
    31–36. Avalie coerência entre fronteiras, falhas, evidências e critérios mensuráveis, não apenas presença de componentes.

Glossário essencial

ACL: lista de controle de acesso que associa identidades ou origens a permissões.

API: interface programável que expõe capacidades segundo um contrato.

Autenticação: verificação de uma identidade ou credencial apresentada.

Autorização: decisão sobre ação, recurso e contexto permitidos a uma identidade.

Backoff: aumento planejado do intervalo entre novas tentativas.

BGP: protocolo usado para trocar alcançabilidade e políticas entre sistemas autônomos.

BOLA: falha de autorização no nível do objeto, permitindo acesso indevido por troca de identificador.

Cache: armazenamento temporário de resultado reutilizável, sujeito a validade e invalidação.

Chave estrangeira: restrição que referencia uma chave de outra relação.

Chave primária: identificador escolhido para cada linha de uma tabela.

CIDR/prefixo: notação que representa os bits de rede de um endereço IP.

Container: processo e recursos isolados que compartilham o kernel do host.

CORS: política dos navegadores para compartilhamento de respostas entre origens.

Deadlock: espera cíclica em que nenhuma atividade participante progride.

DNS autoritativo: servidor que publica dados oficiais de uma zona.

DNS recursivo: servidor que resolve consultas em nome de clientes e mantém cache.

Endpoint: ponto endereçável de comunicação; em API, combinação de destino e operação segundo o contrato.

Firewall: mecanismo que aplica política a fluxos de rede.

Header HTTP: campo de metadados de uma requisição ou resposta.

Idempotência: propriedade pela qual repetir a mesma operação produz o mesmo efeito pretendido de uma execução.

Índice: estrutura auxiliar que acelera certos acessos e adiciona custo de armazenamento e escrita.

Isolamento transacional: controle sobre interferência observável entre transações concorrentes.

Jitter: variação aleatória adicionada ao intervalo de retentativa para evitar sincronização de clientes.

JSON: formato textual de intercâmbio definido por objetos, arrays e valores básicos.

Kernel: núcleo privilegiado que gerencia recursos e mecanismos fundamentais do sistema operacional.

Latência: tempo necessário para concluir ou avançar uma operação; deve ser medida com escopo e percentil.

NAT: tradução de endereços e/ou portas entre contextos de rede.

Observabilidade: capacidade de inferir estado interno a partir de sinais como logs, métricas e traces.

OpenAPI: especificação para descrever interfaces de APIs HTTP de forma independente de linguagem.

OpenID Connect: camada de identidade construída sobre OAuth 2.0.

OAuth 2.0: framework para autorização delegada e acesso limitado a recursos.

Page fault: evento em que o acesso a uma página exige intervenção do sistema de memória.

PITR: recuperação de banco para um ponto no tempo usando base e registros de alterações.

Porta: identificador usado pelo transporte para entregar dados ao serviço apropriado.

Processo: instância de programa em execução com contexto e recursos.

Proxy reverso: intermediário que recebe solicitações em nome de servidores de origem.

QUIC: protocolo de transporte seguro e multiplexado sobre UDP, usado pelo HTTP/3.

Réplica: cópia que acompanha alterações de outra instância para leitura ou disponibilidade.

REST: estilo arquitetural definido por um conjunto de restrições para sistemas em hipermídia.

RPO: quantidade máxima de perda de dados tolerável medida no tempo.

RTO: tempo alvo para restabelecer o serviço após interrupção.

Schema: definição das estruturas, tipos, relações e restrições de um banco ou mensagem.

Serviço: função de longa duração com política de ciclo de vida gerenciada.

Socket: abstração de comunicação associada a protocolo e endpoints.

SGBD: software que define, consulta, coordena, protege e recupera bancos de dados.

Sistema autônomo: conjunto de redes sob política administrativa comum no roteamento interdomínio.

Swap: área secundária que pode armazenar páginas retiradas da RAM; não possui desempenho equivalente.

TCP: transporte orientado a conexão que fornece fluxo ordenado e confiável de bytes.

Thread: fluxo de execução escalonável dentro de um processo.

Thrashing: atividade excessiva de paginação que deixa pouco progresso útil.

TLS: protocolo que protege o canal e autentica pares segundo credenciais e políticas configuradas.

Trace: registro causal do percurso e das operações de uma solicitação distribuída.

Transação: unidade de operações confirmada ou desfeita segundo as garantias do SGBD.

TTL: duração pela qual uma resposta DNS pode permanecer válida em cache.

UDP: transporte de datagramas com garantias básicas, sem entrega e ordem incorporadas.

VLAN: separação lógica de domínios de enlace em infraestrutura compatível.

Webhook: notificação HTTP iniciada pelo produtor quando ocorre um evento.


Referências técnicas e bibliográficas

As referências abaixo combinam livros fundamentais e especificações primárias. Protocolos e APIs evoluem; em implementação, confirme erratas, versões suportadas e documentação do produto instalado.

[1] SILBERSCHATZ, Abraham; GALVIN, Peter B.; GAGNE, Greg. Operating System Concepts. Wiley.

[2] TANENBAUM, Andrew S.; BOS, Herbert. Modern Operating Systems. Pearson.

[3] MICROSOFT. Processes and Threads — Win32 API. Disponível em: https://learn.microsoft.com/en-us/windows/win32/api/_processthreadsapi/.

[4] DOCKER. What is a container? Disponível em: https://docs.docker.com/get-started/docker-concepts/the-basics/what-is-a-container/.

[5] DOCKER. Docker Engine security. Disponível em: https://docs.docker.com/engine/security/.

[6] TANENBAUM, Andrew S.; WETHERALL, David J. Computer Networks. Pearson.

[7] IETF. RFC 1918 — Address Allocation for Private Internets. Disponível em: https://www.rfc-editor.org/info/rfc1918.

[8] IETF. RFC 9293 — Transmission Control Protocol (TCP). Disponível em: https://www.rfc-editor.org/info/rfc9293.

[9] IETF. RFC 768 — User Datagram Protocol. Disponível em: https://www.rfc-editor.org/info/rfc768.

[10] IETF. RFC 1034 — Domain Names — Concepts and Facilities; RFC 1035 — Domain Names — Implementation and Specification. Disponíveis em: https://www.rfc-editor.org/info/rfc1034 e https://www.rfc-editor.org/info/rfc1035.

[11] IETF. RFC 9499 — DNS Terminology. Disponível em: https://www.rfc-editor.org/info/rfc9499.

[12] IETF. RFC 9110 — HTTP Semantics. Disponível em: https://www.rfc-editor.org/rfc/rfc9110.html.

[13] IETF. RFC 9113 — HTTP/2. Disponível em: https://www.rfc-editor.org/info/rfc9113.

[14] IETF. RFC 9114 — HTTP/3. Disponível em: https://www.rfc-editor.org/info/rfc9114.

[15] IETF. RFC 9846 — The Transport Layer Security (TLS) Protocol Version 1.3. Disponível em: https://www.rfc-editor.org/info/rfc9846.

[16] IETF. RFC 10008 — The HTTP QUERY Method. Disponível em: https://www.rfc-editor.org/info/rfc10008.

[17] FIELDING, Roy T. Architectural Styles and the Design of Network-based Software Architectures, capítulo 5. Disponível em: https://www.ics.uci.edu/~fielding/pubs/dissertation/rest_arch_style.htm.

[18] OPENAPI INITIATIVE. OpenAPI Specification 3.2.0. Disponível em: https://spec.openapis.org/oas/v3.2.0.html.

[19] IETF. RFC 8259 — The JavaScript Object Notation (JSON) Data Interchange Format. Disponível em: https://www.rfc-editor.org/info/rfc8259.

[20] IETF. RFC 6749 — The OAuth 2.0 Authorization Framework. Disponível em: https://www.rfc-editor.org/info/rfc6749.

[21] IETF. RFC 9700 — Best Current Practice for OAuth 2.0 Security. Disponível em: https://www.rfc-editor.org/info/rfc9700.

[22] OWASP. OWASP Top 10 API Security Risks — 2023. Disponível em: https://owasp.org/API-Security/editions/2023/en/0x11-t10/.

[23] OPEN TELEMETRY. Signals e Context propagation. Disponíveis em: https://opentelemetry.io/docs/concepts/signals/ e https://opentelemetry.io/docs/concepts/context-propagation/.

[24] POSTGRESQL GLOBAL DEVELOPMENT GROUP. Transaction Isolation. Disponível em: https://www.postgresql.org/docs/current/transaction-iso.html.

[25] ORACLE. MySQL 8.4 Reference Manual — InnoDB and the ACID Model. Disponível em: https://dev.mysql.com/doc/refman/8.4/en/mysql-acid.html.

[26] POSTGRESQL GLOBAL DEVELOPMENT GROUP. Backup and Restore. Disponível em: https://www.postgresql.org/docs/current/backup.html.

[27] POSTGRESQL GLOBAL DEVELOPMENT GROUP. Continuous Archiving and Point-in-Time Recovery. Disponível em: https://www.postgresql.org/docs/current/continuous-archiving.html.

[28] ORACLE. MySQL 8.4 Reference Manual — Clustered and Secondary Indexes. Disponível em: https://dev.mysql.com/doc/refman/8.4/en/innodb-index-types.html.

[29] GLPI PROJECT. Database model. Disponível em: https://glpi-developer-documentation.readthedocs.io/en/master/devapi/database/dbmodel.html.

[30] GLPI PROJECT. Actors. Disponível em: https://help.glpi-project.org/documentation/modules/assistance/actors.

[31] GLPI PROJECT. API — General configuration. Disponível em: https://help.glpi-project.org/documentation/modules/configuration/general/api/api.

[32] NGINX. Module ngx_http_proxy_module. Disponível em: https://nginx.org/en/docs/http/ngx_http_proxy_module.html.

[33] MOZILLA DEVELOPER NETWORK. Cross-Origin Resource Sharing (CORS). Disponível em: https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/CORS.

[34] KUROSE, James F.; ROSS, Keith W. Computer Networking: A Top-Down Approach. Pearson.

[35] KLEPPMANN, Martin. Designing Data-Intensive Applications. O’Reilly Media.

[36] GLPI PROJECT. Issue #1926 — actors type identifiers in glpi_tickets_users. Disponível em: https://github.com/glpi-project/glpi/issues/1926.

Leituras de aprofundamento


Encerramento da Parte 2

Sistemas operacionais, redes, Internet, APIs e bancos de dados não são degraus independentes. São abstrações empilhadas, cada uma com promessas, estados e formas próprias de falhar.

O sistema operacional não “roda o site” de maneira abstrata: ele agenda threads, mapeia memória, abre sockets e aplica identidades. A rede não “leva a Internet”: ela encaminha pacotes segundo endereços, rotas e políticas. DNS não torna a aplicação saudável; apenas ajuda a localizar dados sobre o destino. TLS não autoriza usuários; protege e autentica o canal conforme sua configuração. HTTP não valida a regra de negócio; expressa uma operação. A API não substitui o banco; governa o acesso a capacidades e invariantes. O banco não descobre a intenção humana; preserva as relações e restrições que foram realmente modeladas.

Essa distinção muda a prática profissional. Em vez de perguntar “qual ferramenta reinicio?”, o analista pergunta:

  • qual promessa foi quebrada?
  • qual camada deveria cumpri-la?
  • qual evidência localiza a primeira divergência?
  • qual mudança corrige a causa sem ampliar o risco?
  • como o sistema mostrará mais cedo a mesma condição no futuro?

Esse raciocínio prepara a Parte 3. O próximo passo aprofundará representação da informação, arquitetura de computadores, sistemas de arquivos, virtualização, cloud computing e segurança. Os conceitos desta parte servirão como base: isolamento dependerá de processos e memória; disponibilidade, de redes e estado; segurança, de identidades e fronteiras; recuperação, de dados e mecanismos verificáveis.


Ficha editorial da Parte 2

Tema central: como sistemas executam, comunicam, integram e persistem dados.
Tese: diagnosticar exige separar camadas, formular hipóteses e correlacionar evidências.
Público: estudantes e profissionais em formação em Análise e Desenvolvimento de Sistemas.
Palavras-chave: sistema operacional, processo, thread, memória virtual, rede, DNS, HTTP, TLS, API, REST, OAuth, integração, SQL, transação, índice, backup, GLPI.
Continuidade: Parte 3 — arquitetura, sistemas de arquivos, virtualização, cloud e segurança da informação.

Fim do artigo Volume I — Parte 2 — Sistemas Operacionais, Redes de Computadores, Internet e Comunicação entre Sistemas