Capa do Ebook gratuito Preparatório Caixa Econômica Federal - Técnico Bancário - Tecnologia da Informação

Preparatório Caixa Econômica Federal - Técnico Bancário - Tecnologia da Informação

Novo curso

20 páginas

Preparatório Caixa TI: Arquitetura, integração e mensageria em sistemas

Capítulo 15

Tempo estimado de leitura: 11 minutos

+ Exercício

Arquitetura em camadas: organizar responsabilidades

Arquitetura em camadas é um padrão de organização em que o sistema é dividido por responsabilidades, reduzindo acoplamento e facilitando manutenção, testes e evolução. Em cenários bancários, é comum separar regras de negócio de detalhes técnicos (banco, mensageria, integrações), para permitir mudanças com menor risco.

Camadas típicas e responsabilidades

  • Apresentação (UI/API): recebe requisições, valida formato, autentica/autoriza (quando aplicável), traduz para comandos de negócio e devolve respostas. Evite regra de negócio aqui.

  • Aplicação (casos de uso): orquestra fluxos (ex.: “registrar pagamento”, “abrir conta”), coordena transações e chamadas a serviços. Concentra regras de processo (workflow).

  • Domínio (regras de negócio): entidades, regras e invariantes (ex.: limites, validações de consistência). Deve ser o mais independente possível de frameworks.

  • Infraestrutura: detalhes técnicos (persistência, mensageria, integrações externas, cache, provedores). Implementa interfaces definidas pelas camadas superiores.

    Continue em nosso aplicativo

    Você poderá ouvir o audiobook com a tela desligada, ganhar gratuitamente o certificado deste curso e ainda ter acesso a outros 5.000 cursos online gratuitos.

    ou continue lendo abaixo...
    Download App

    Baixar o aplicativo

Exemplo prático: fluxo em camadas

Cenário: um serviço de Pagamentos recebe uma solicitação para registrar um pagamento e notificar outros sistemas.

  • API: valida campos obrigatórios e converte JSON em um comando (ex.: RegistrarPagamento).

  • Aplicação: chama o domínio para validar regras, persiste e publica um evento (ex.: PagamentoRegistrado).

  • Domínio: garante invariantes (ex.: impedir duplicidade por chave de negócio).

  • Infra: grava no banco e envia mensagem para um broker (fila/tópico).

Passo a passo prático: desenhando camadas para um caso de uso

  • 1) Liste casos de uso: “Criar proposta”, “Aprovar proposta”, “Efetivar contrato”.

  • 2) Defina entradas/saídas: dados necessários, resposta esperada, erros.

  • 3) Separe regras: o que é invariável (domínio) vs o que é fluxo (aplicação).

  • 4) Defina portas (interfaces): repositórios, publicadores de eventos, clientes de serviços externos.

  • 5) Implemente adaptadores: banco, mensageria, HTTP clients.

  • 6) Garanta testabilidade: domínio e aplicação testáveis sem dependências externas (mock das portas).

Monólito vs microserviços: comparação objetiva

Monólito e microserviços são estilos arquiteturais. A escolha impacta implantação, escalabilidade, governança, confiabilidade e complexidade operacional.

Monólito

  • O que é: uma aplicação única (um artefato/implantação) com módulos internos.

  • Vantagens: deploy mais simples, transações locais mais fáceis, depuração direta, menor sobrecarga de rede.

  • Desvantagens: escalabilidade geralmente “em bloco”, risco de acoplamento entre módulos, releases podem ficar pesados, falhas podem impactar mais áreas se não houver isolamento interno.

Microserviços

  • O que é: conjunto de serviços pequenos e independentes, cada um com responsabilidade clara, comunicando-se via rede (HTTP/gRPC/mensageria).

  • Vantagens: escalabilidade por serviço, deploy independente, isolamento de falhas (se bem projetado), autonomia de times.

  • Desvantagens: maior complexidade (latência, retries, versionamento de contratos), dados distribuídos, consistência eventual, necessidade forte de observabilidade e automação.

Critérios práticos de escolha

  • Limites de domínio claros: se há responsabilidades bem separadas e evolução independente, microserviços tendem a ser adequados.

  • Escalabilidade desigual: se um componente precisa escalar muito mais que outros (ex.: processamento de eventos), microserviços ajudam.

  • Maturidade operacional: sem automação de deploy, monitoramento e resposta a incidentes, microserviços aumentam risco.

  • Velocidade inicial: para começar com menor custo operacional, um monólito modular costuma ser melhor.

Comparação direta (resumo)

  • Deploy: monólito (1 unidade) vs microserviços (múltiplas unidades).

  • Falhas: monólito (impacto potencial maior) vs microserviços (isolamento possível, mas risco de cascata via rede).

  • Dados: monólito (transações locais) vs microserviços (integração por eventos, consistência eventual).

  • Performance: monólito (chamadas internas rápidas) vs microserviços (latência de rede, serialização, retries).

  • Complexidade: monólito (menor) vs microserviços (maior, exige governança e observabilidade).

Integração síncrona vs assíncrona

Integração é como sistemas trocam informações e coordenam ações. A distinção central é: esperar resposta imediata (síncrona) ou desacoplar por mensagens/eventos (assíncrona).

Integração síncrona

  • Conceito: o sistema A chama o sistema B e aguarda resposta (ex.: HTTP/gRPC). O resultado depende da resposta imediata.

  • Quando usar: consulta em tempo real, validações que precisam de resposta imediata, operações curtas.

  • Implicações: precisa de timeout, retry com cuidado e circuit breaker para evitar falhas em cascata; latência do B vira latência do A.

Integração assíncrona

  • Conceito: o sistema A publica uma mensagem/evento e segue; o sistema B processa depois, via broker.

  • Quando usar: processamento demorado, picos de carga, desacoplamento entre sistemas, workflows distribuídos.

  • Implicações: consistência eventual, duplicidade de mensagens, necessidade de idempotência e rastreabilidade ponta a ponta.

Passo a passo prático: decidir síncrono ou assíncrono

  • 1) Precisa responder ao usuário agora? Se sim, tende a ser síncrono ou híbrido (responde “recebido” e processa assíncrono).

  • 2) A operação pode demorar ou ter picos? Se sim, assíncrono reduz timeouts e melhora resiliência.

  • 3) A dependência é instável? Assíncrono ajuda a absorver indisponibilidades temporárias.

  • 4) Exige consistência forte imediata? Síncrono facilita, mas evite transações distribuídas; prefira compensações quando possível.

  • 5) Precisa auditar e rastrear? Ambos precisam, mas assíncrono exige correlação de eventos e observabilidade mais robusta.

Mensageria: filas, tópicos e padrões de comunicação

Mensageria é o uso de um intermediário (broker) para transportar mensagens entre produtores e consumidores. Ela permite desacoplamento, buffer de carga e maior tolerância a falhas.

Fila (queue)

  • Modelo: ponto a ponto. Uma mensagem é consumida por um consumidor (dentro de um grupo concorrente).

  • Uso típico: processamento de tarefas (ex.: gerar documento, processar lote), balanceamento de carga entre workers.

  • Implicação: aumenta throughput com consumidores paralelos; exige controle de concorrência e idempotência.

Tópico (topic)

  • Modelo: publicação/assinatura. Uma mensagem pode ser entregue a vários consumidores (cada um com sua assinatura/grupo).

  • Uso típico: eventos de negócio (ex.: PagamentoConfirmado) consumidos por antifraude, notificações, conciliação, analytics.

  • Implicação: facilita integração entre múltiplos sistemas sem acoplamento direto; exige governança de contratos de eventos.

Comandos vs eventos

  • Comando: “faça algo” (intenção). Ex.: ProcessarPagamento. Normalmente direcionado a um responsável.

  • Evento: “algo aconteceu” (fato). Ex.: PagamentoProcessado. Pode interessar a vários consumidores.

Garantias de entrega: pelo menos uma vez vs exatamente uma vez (conceitual)

Ao usar mensageria, é essencial entender as garantias de entrega, pois elas afetam duplicidade, perda e complexidade de processamento.

Pelo menos uma vez (at-least-once)

  • Conceito: a mensagem será entregue uma ou mais vezes. Duplicatas podem ocorrer (ex.: consumidor processa, mas falha antes do ack).

  • Implicação: o consumidor deve ser idempotente (processar duplicatas sem efeitos colaterais indevidos).

  • Vantagem: reduz chance de perda; é comum e mais simples de operar.

Exatamente uma vez (exactly-once) em nível conceitual

  • Conceito: o efeito do processamento ocorre uma única vez, mesmo com falhas e retries.

  • Interpretação prática: muitas vezes significa “exatamente uma vez no efeito” (sem duplicar gravações/ações), usando deduplicação, controle de offsets e/ou transações no pipeline.

  • Custo: maior complexidade e, frequentemente, impacto em desempenho/latência.

Idempotência: o antídoto contra duplicidade

Uma operação idempotente pode ser executada várias vezes com o mesmo resultado final. Em mensageria, isso é crucial porque duplicatas são esperadas em muitas configurações.

Estratégias comuns de idempotência

  • Chave idempotente: incluir um identificador único (ex.: eventId, requestId) e registrar o que já foi processado.

  • Deduplicação por chave de negócio: usar uma chave natural (ex.: “id da transação”) para impedir reprocessamento.

  • Upsert/merge: gravar de forma que repetição não crie novos registros (inserir se não existe, senão atualizar).

  • Inbox/Outbox (conceito): controlar consumo/publicação com persistência de estado para reduzir janelas de inconsistência entre banco e broker.

Passo a passo prático: consumidor idempotente (modelo mental)

  • 1) Receba a mensagem com eventId e dados.

  • 2) Verifique se o eventId já foi processado (registro de deduplicação/inbox).

  • 3) Se já processado, finalize sem repetir efeitos.

  • 4) Se não processado, aplique a mudança (ex.: atualizar status, gerar lançamento).

  • 5) Registre o eventId como processado com metadados (timestamp, origem).

  • 6) Confirme (ack) a mensagem após persistir o estado, reduzindo risco de duplicar efeitos.

// Pseudofluxo conceitual de idempotência no consumo onMessage(msg):   if inbox.exists(msg.eventId):     ack(msg)     return   beginTransaction()     applyBusinessEffect(msg)     inbox.save(msg.eventId, processedAt=now)   commit()   ack(msg)

Consistência eventual: o que esperar em integrações assíncronas

Consistência eventual significa que, após uma mudança, diferentes partes do sistema podem ficar temporariamente divergentes, mas convergem com o tempo. Isso é comum quando eventos propagam alterações entre serviços.

Exemplo prático

  • Serviço A registra “pagamento aprovado” e publica um evento.

  • Serviço B (notificações) consome o evento e envia mensagem alguns segundos depois.

  • Durante esse intervalo, o usuário pode ver o pagamento aprovado, mas ainda não recebeu a notificação.

Cuidados e técnicas associadas

  • Estados intermediários: modelar status como “PENDENTE/PROCESSANDO/CONFIRMADO” para refletir o fluxo real.

  • Reprocessamento seguro: permitir retry sem efeitos duplicados (idempotência).

  • Compensação: se uma etapa posterior falhar, executar ação compensatória (ex.: estornar) em vez de depender de transação distribuída.

Observabilidade: logs, métricas e traces

Observabilidade é a capacidade de entender o que está acontecendo em produção a partir de sinais gerados pelo sistema. Em arquiteturas distribuídas, ela é indispensável para detectar falhas, medir desempenho e investigar incidentes.

Logs

  • O que registrar: início/fim de processamento, erros, timeouts, retries, decisões de negócio relevantes, IDs de correlação.

  • Boa prática: logs estruturados com campos como service, operation, eventId, correlationId, durationMs.

Métricas

  • Exemplos: taxa de requisições, latência p95/p99, taxa de erro, tamanho de fila/lag, throughput de consumo, retries por minuto.

  • Uso: alertas, capacidade, detecção de degradação e gargalos.

Traces (rastreamento distribuído)

  • Conceito: acompanha um fluxo ponta a ponta, atravessando serviços, filas e chamadas externas, medindo tempos e identificando gargalos.

  • Valor: localizar onde a latência aumenta (dependência externa, banco, consumidor lento, serialização).

Correlação de eventos: conectar o que aconteceu

Correlação usa identificadores para relacionar logs, mensagens e spans de trace do mesmo fluxo. Em mensageria, isso é essencial para investigar duplicidade, atrasos e falhas intermitentes.

  • IDs comuns:

    • correlationId: identifica a jornada/fluxo de negócio.

    • causationId: identifica o evento/comando que causou o evento atual.

    • eventId: identifica unicamente a mensagem (útil para deduplicação).

  • Passo a passo prático: propagação de correlação:

    • 1) Na entrada (API), gere/extraia um correlationId.

    • 2) Inclua o correlationId em logs e em chamadas síncronas (headers).

    • 3) Ao publicar mensagem, inclua correlationId, eventId e causationId nos metadados.

    • 4) No consumidor, reutilize o correlationId em logs/traces e propague para novos eventos.

    • 5) Em erros, registre também tentativa, fila/tópico e motivo do retry para facilitar reprocessamento.

// Exemplo conceitual de metadados de mensagem {   "eventId": "uuid-...",   "correlationId": "uuid-...",   "causationId": "uuid-...",   "type": "PagamentoRegistrado",   "occurredAt": "2026-01-15T10:00:00Z" }

Questões (estilo prova): escolha de padrões e implicações

1) Monólito vs microserviços

  • Um sistema precisa de deploys independentes por área e escalabilidade muito maior apenas no módulo de processamento. Qual estilo tende a atender melhor e qual o principal custo associado?

  • Em um ambiente com pouca automação e equipe reduzida, qual abordagem tende a reduzir risco operacional? Justifique com base em complexidade e observabilidade.

2) Síncrono vs assíncrono

  • Para uma validação que precisa bloquear a operação imediatamente (ex.: checagem obrigatória antes de confirmar), qual integração é mais adequada? Quais mecanismos de confiabilidade devem acompanhar (timeout, retry, circuit breaker)?

  • Para absorver picos de solicitações sem derrubar dependências, qual integração é mais adequada? Quais implicações surgem em consistência e duplicidade?

3) Filas e tópicos

  • Qual a diferença prática entre fila e tópico quanto ao número de consumidores que recebem a mesma mensagem?

  • Em qual cenário faz mais sentido publicar um evento em tópico em vez de enviar um comando em fila?

4) Garantias de entrega e idempotência

  • Explique por que “pelo menos uma vez” exige idempotência no consumidor e qual falha típica gera duplicidade.

  • Quais são duas estratégias para tornar o processamento idempotente? Cite uma baseada em eventId e outra baseada em chave de negócio.

5) Desempenho e confiabilidade

  • Como a escolha por microserviços pode aumentar latência em comparação ao monólito? Cite dois fatores.

  • Como mensageria pode aumentar confiabilidade em picos e indisponibilidades? Qual o trade-off em termos de consistência?

6) Observabilidade e correlação

  • Qual a função de logs, métricas e traces, e como eles se complementam em incidentes?

  • Por que correlationId e causationId são importantes em fluxos assíncronos? Dê um exemplo de investigação que depende desses IDs.

Agora responda o exercício sobre o conteúdo:

Em um cenário de mensageria com garantia de entrega “pelo menos uma vez”, qual prática é essencial no consumidor para evitar efeitos colaterais indevidos quando houver duplicidade de mensagens?

Você acertou! Parabéns, agora siga para a próxima página

Você errou! Tente novamente.

Em “pelo menos uma vez”, duplicatas podem ocorrer (ex.: falha antes do ack). Por isso o consumidor deve ser idempotente, deduplicando por eventId ou chave de negócio, e realizar o ack após persistir o estado para evitar repetir efeitos.

Próximo capitúlo

Preparatório Caixa TI: Fundamentos de dados, analytics e qualidade da informação

Arrow Right Icon
Baixe o app para ganhar Certificação grátis e ouvir os cursos em background, mesmo com a tela desligada.