Como projetar comunicação assíncrona, entrega confiável, roteamento, replay e processamento distribuído em plataformas corporativas
Edição aprofundada - material de estudo e consulta profissional
Por João Ricardo Dutra••Material integral
Mensageria: desacoplar tempo, capacidade e disponibilidade
Figura de abertura - Brokers desacoplam produtores e consumidores, mas a confiabilidade continua sendo responsabilidade ponta a ponta.
Princípio central
Confiabilidade depende do protocolo, do e do comportamento correto de produtores e consumidores.
Edição aprofundada - material de estudo e consulta profissional
Apresentação do capítulo
Mensageria é uma das bases de arquiteturas distribuídas. Em vez de exigir que dois sistemas estejam disponíveis ao mesmo tempo e concluam uma interação no mesmo intervalo, um produtor publica uma mensagem em um intermediário e um ou mais consumidores processam essa mensagem quando possuem capacidade. Esse desacoplamento temporal reduz dependências diretas, absorve picos e permite compor fluxos assíncronos de negócio.
A palavra mensageria, porém, cobre modelos diferentes. Uma fila tradicional distribui unidades de trabalho para consumidores e tende a remover ou confirmar mensagens após o processamento. Um distribuído mantém registros por um período e permite que consumidores independentes avancem seus próprios offsets ou façam . Um sistema de publish/subscribe entrega cópias lógicas a vários grupos interessados. Cada modelo altera ordering, retenção, escalabilidade e recuperação.
Kafka e RabbitMQ são frequentemente comparados como concorrentes, mas nasceram com ênfases distintas. Kafka organiza eventos em tópicos particionados e persistentes, otimizados para retenção, e alto throughput. RabbitMQ é um de mensageria com roteamento flexível por exchanges, filas, acknowledgements e diferentes tipos de fila. AMQP pode significar tanto o modelo 0-9-1 associado ao RabbitMQ quanto o protocolo padronizado AMQP 1.0. JMS, hoje Jakarta Messaging, é uma Java e não um ou protocolo único.
Este capítulo constrói um modelo mental que começa em mensagens, confirmação, ordering e ; aprofunda Kafka e RabbitMQ; diferencia AMQP 0-9-1 de AMQP 1.0; explica a abstração JMS; e encerra com padrões de integração, segurança, observabilidade, capacidade e . O objetivo é permitir decisões técnicas conscientes, não apenas ensinar comandos de um produto.
Como estudar este capítulo
Para cada fluxo, escreva quem produz, onde a mensagem fica armazenada, como o confirma recebimento, quando o consumidor confirma processamento, qual é a unidade de ordering e como duplicatas serão tratadas. Sem essas respostas, a promessa de entrega permanece ambígua.
Objetivos de aprendizagem
Explicar por que mensageria desacopla tempo, capacidade e disponibilidade entre sistemas.
Distinguir fila, tópico, distribuído, publish/subscribe e .
Compreender acknowledgements, confirms, offsets e semânticas de entrega.
Relacionar ordering, partições, consumer groups, e .
Descrever a arquitetura do Kafka, incluindo tópicos, partições, réplicas, líderes e .
Descrever a arquitetura do RabbitMQ, incluindo exchanges, queues, bindings, vhosts e channels.
Diferenciar AMQP 0-9-1 e AMQP 1.0.
Explicar Jakarta Messaging/JMS como de programação e abstração de provider.
Projetar DLQ, , Outbox, Inbox, -reply e competing consumers.
Aplicar segurança, observabilidade, planejamento de capacidade e .
Estrutura do capítulo
31.1 Fundamentos de mensageria e desacoplamento
31.2 Fila, publish/subscribe, e distribuído
31.3 Mensagens, envelopes, e contratos
31.4 Acknowledgements, confirms e semânticas de entrega
31.5 Ordering, partições, e duplicatas
31.6 Kafka: arquitetura, produtores e consumidores
31.7 Retenção, compactação, , Connect e
31.8 RabbitMQ: exchanges, filas, bindings e routing
31.9 Confiabilidade, quorum queues, , DLX e
31.10 AMQP 0-9-1 e AMQP 1.0
31.11 Jakarta Messaging/JMS
31.12 Padrões de integração, segurança, observabilidade e
Resumo, checklist, exercícios, glossário e referências
31.1 Fundamentos de mensageria e desacoplamento
Em uma chamada síncrona, o consumidor depende da disponibilidade e do tempo de resposta do provedor. Em um fluxo assíncrono, o produtor transfere a responsabilidade imediata para um ou , recebe uma confirmação apropriada e segue seu processamento. O consumidor pode trabalhar depois, respeitando sua própria capacidade. Essa diferença altera a arquitetura de falhas: indisponibilidade temporária do consumidor não precisa impedir a publicação, desde que o possua armazenamento e capacidade suficientes.
O desacoplamento não é absoluto. Produtores e consumidores continuam compartilhando contrato, semântica, expectativa de prazo e regras de negócio. Uma mensagem pode estar tecnicamente entregue e ainda ser semanticamente inválida. Um consumidor pode confirmar cedo demais e perder trabalho, ou confirmar tarde demais e provocar duplicatas. Por isso, mensageria precisa de contrato, ownership, observabilidade e estratégia de recuperação.
A decisão entre síncrono e assíncrono deve observar o significado do resultado. Consultas que precisam responder imediatamente ao usuário normalmente permanecem síncronas. Processos longos, integração com múltiplos sistemas, absorção de picos e propagação de eventos se beneficiam de assincronicidade. Muitos fluxos combinam ambos: uma aceita o comando, persiste estado e publica um evento; o cliente acompanha a conclusão por consulta, ou canal de notificação.
31.2 Fila, publish/subscribe, e distribuído
Fila é uma estrutura em que mensagens aguardam consumidores. No padrão competing consumers, várias instâncias compartilham a fila e cada mensagem é processada por apenas uma delas. Publish/subscribe cria múltiplas assinaturas ou filas lógicas para que grupos diferentes recebam o mesmo evento. O termo tópico pode representar uma entidade de roteamento, uma categoria de publicação ou um particionado, dependendo da tecnologia.
Kafka trata um tópico como um dividido em partições. Registros permanecem conforme políticas de retenção ou compactação, e consumidores registram offsets. Isso permite , múltiplos grupos independentes e reconstrução de projeções. RabbitMQ usa exchanges para rotear mensagens a filas ou ; consumidores normalmente recebem de filas e confirmam processamento. do RabbitMQ acrescentam retenção e leitura por , aproximando-se de casos de .
Escolher o modelo correto é mais importante do que escolher o produto por marca. Trabalho exclusivo e comandos direcionados combinam bem com filas. Eventos de domínio destinados a vários consumidores pedem fan-out ou grupos independentes. Histórico reprocessável, analytics e event favorecem . Um sistema pode usar mais de um modelo ao mesmo tempo.
Fila tradicional e distribuído preservam estados diferentes
Figura 1 - Filas e diferem principalmente no ciclo de vida da mensagem e na posição mantida pelo consumidor.
Tabela 1 - O nome tópico não possui exatamente a mesma semântica em todas as plataformas.
Modelo
Unidade de consumo
Retenção típica
Uso recorrente
Fila
Uma mensagem para um consumidor do grupo.
Até ack, expiração ou descarte.
Comandos, tarefas e integração operacional.
Pub/sub
Uma cópia lógica por assinatura ou grupo.
Conforme cada destino.
Eventos para múltiplos domínios.
Log particionado
Offset por partição e grupo.
Por tempo, tamanho ou compactação.
Replay, analytics e event streaming.
Stream persistente
Leitura sequencial com offset.
Retenção configurada.
Telemetria, eventos e fan-out durável.
31.3 Mensagens, envelopes, e contratos
Uma mensagem possui e metadados. O carrega o dado de negócio; ou properties carregam informações como tipo, versão, correlation ID, content type, timestamp, context, prioridade, expiração e chave de particionamento. Misturar metadados de transporte com regras de negócio dificulta migração entre brokers e pode criar dependência excessiva de uma biblioteca específica.
Contratos de eventos precisam definir semântica, não apenas . O nome do evento deve indicar algo que ocorreu, como PagamentoAutorizado, e não uma instrução ambígua. O precisa informar campos obrigatórios, nullability, tipos, unidades, precisão, identificadores e compatibilidade. Avro, e Protobuf são opções comuns, mas a governança depende de regras de evolução, catálogo e testes.
Envelopes padronizados facilitam correlação e observabilidade. Entretanto, replicar toda a entidade em cada evento pode expor dados desnecessários e aumentar acoplamento. Publicar apenas um identificador pode obrigar consumidores a fazer chamadas síncronas. A decisão deve equilibrar autonomia, privacidade, tamanho, consistência e frequência de mudança.
31.4 Acknowledgements, confirms e semânticas de entrega
Confiabilidade precisa ser analisada por trecho. O produtor envia ao e precisa saber se a mensagem foi aceita com o nível de durabilidade requerido. Depois, o entrega ao consumidor e precisa saber se o processamento terminou. Publisher confirms e consumer acknowledgements resolvem essas duas relações separadas. Um confirm do não prova que o consumidor concluiu a regra de negócio.
At-most-once aceita a possibilidade de perda para evitar repetição: a mensagem pode ser considerada concluída antes do processamento. At-least-once privilegia não perder, mas aceita duplicatas quando há falha após o efeito de negócio e antes do . Exactly-once é uma propriedade contextual, normalmente limitada a fronteiras específicas. Não significa que qualquer efeito externo, banco ou remota será magicamente executado uma única vez.
Em sistemas reais, at-least-once com é a base mais comum. O consumidor registra um identificador processado ou usa uma operação naturalmente idempotente, executa o efeito e confirma depois. Se a mensagem reaparecer, o mesmo resultado é preservado. Quando o efeito e o registro de deduplicação não compartilham transação, ainda existem janelas de falha que precisam ser tratadas pelo desenho.
Figura 2 - Confirmação de publicação e confirmação de processamento são mecanismos ortogonais.
Tabela 2 - A semântica deve ser definida ponta a ponta, não apenas pelo nome do recurso do broker.
Semântica
O que privilegia
Risco residual
At-most-once
Evitar repetição.
Mensagem pode ser perdida.
At-least-once
Evitar perda.
Consumidor deve tolerar duplicatas.
Exactly-once contextual
Uma transação ou pipeline controlado.
Efeitos externos podem ficar fora da garantia.
31.5 Ordering, partições, e duplicatas
Ordering global reduz paralelismo e é caro. A maioria das plataformas preserva ordem apenas dentro de uma fila, partição, canal ou sessão, e mesmo essa ordem pode ser alterada por requeue, prioridade, múltiplos produtores ou processamento concorrente. A arquitetura deve definir qual entidade precisa de ordem: conta, pedido, cliente ou agregado. Essa entidade costuma orientar a chave de particionamento ou o destino da mensagem.
Uma chave estável concentra eventos relacionados na mesma partição, mas pode produzir hot partitions se a distribuição for desigual. Chaves aleatórias melhoram balanceamento, porém perdem ordering por entidade. O consumidor também precisa processar de forma compatível: várias threads sobre a mesma partição podem concluir fora de ordem se não houver coordenação.
Duplicatas surgem em de produtor, reentrega após falha, e reprocessamento intencional. pode usar chave de negócio, versão do agregado, tabela Inbox, compare-and-set, upsert ou controle de sequência. A solução deve definir por quanto tempo a deduplicação é mantida e qual é o comportamento quando uma mensagem antiga reaparece.
Modelo mental
Pergunte sempre: ordem entre quais mensagens, dentro de qual unidade, observada por qual consumidor e durante qual janela? Dizer apenas que o preserva ordem é insuficiente.
31.6 Kafka: arquitetura distribuída
Kafka organiza dados em tópicos particionados. Cada partição é um ordenado de registros identificados por offsets crescentes. Uma partição possui uma réplica líder que atende leituras e escritas e réplicas seguidoras que acompanham o . Replicação aumenta tolerância a falhas, mas a durabilidade percebida depende de configurações de produtor, quantidade de réplicas e conjunto de réplicas sincronizadas.
Brokers armazenam partições e atendem clientes. A metadata do é coordenada pelo modo , baseado em quorum de controladores. A separação entre brokers e controladores pode ser física ou lógica, conforme o porte e a topologia. Planejamento de capacidade considera disco sequencial, page , rede, quantidade de partições, replicação, retenção e padrão de acesso.
Tópicos não são filas exclusivas. Vários consumer groups podem ler o mesmo tópico de maneira independente. Dentro de um grupo, cada partição ativa é atribuída a apenas um consumidor por vez, o que limita o paralelismo útil ao número de partições. Adicionar consumidores além desse número não aumenta throughput daquele grupo.
Figura 3 - O Kafka combina partições, replicação e consumer groups para escalar armazenamento e consumo.
31.7 Produtores, consumidores, offsets e transações no Kafka
O produtor escolhe tópico, chave, e . A chave pode determinar a partição, e o batching agrupa registros para melhorar eficiência. A configuração controla quando a publicação é considerada concluída. Idempotent producer evita duplicação causada por dentro das garantias suportadas pelo protocolo. Isso não torna automaticamente idempotente um consumidor que grava em outro banco.
Consumidores fazem parte de grupos, recebem partições e controlam offsets. Commit antecipado pode perder processamento; commit tardio pode causar reentrega. Rebalances redistribuem partições quando membros entram, saem ou alteram assinatura. Estratégias cooperativas e tratamento correto de revogação reduzem pausas, mas o consumidor precisa finalizar ou interromper trabalho de maneira segura.
Transações Kafka podem agrupar publicações e commits de offsets para consume-transform-produce dentro do ecossistema Kafka. Com isolation apropriado, consumidores evitam ler registros abortados. A garantia não se estende automaticamente a bancos externos, e-mails ou chamadas . Para esses efeitos, Outbox, Inbox e continuam relevantes.
Tabela 3 - A confiabilidade do Kafka emerge da combinação de várias decisões.
Elemento
Decisão técnica
Impacto
Chave
Entidade usada no particionamento.
Ordering e distribuição de carga.
acks
Nível de confirmação do cluster.
Durabilidade e latência.
Offset commit
Momento em que o grupo avança.
Perda ou duplicação após falha.
Rebalance
Redistribuição de partições.
Pausas, revogação e paralelismo.
Transação
Publicações e offsets atômicos no Kafka.
Exactly-once dentro de fronteiras controladas.
31.8 Retenção, compactação, , Kafka Connect e Kafka
Retenção por tempo ou tamanho remove segmentos antigos independentemente de todos os consumidores terem lido. O dimensionamento precisa garantir que consumidores atrasados não ultrapassem a janela de retenção. compaction preserva, de forma eventual, o registro mais recente por chave e é útil para changelogs e reconstrução de estado. Tombstones representam remoções no modelo compactado.
é um recurso poderoso e perigoso. Reposicionar offsets permite reconstruir projeções e corrigir consumidores, mas também pode repetir efeitos externos. Antes de reprocessar, o time deve separar consumidores puramente determinísticos daqueles que enviam e-mail, debitam valores ou chamam terceiros. Ambientes de , tópicos de saída separados e dry-run reduzem risco.
Kafka Connect padroniza integração com fontes e destinos por connectors, tasks e offsets. Kafka oferece biblioteca para transformações, joins, janelas e state stores. Esses componentes não eliminam decisões de , semântica, partição e tratamento de erros; eles fornecem runtime e abstrações para implementá-las.
31.9 RabbitMQ: arquitetura, exchanges, filas e bindings
RabbitMQ recebe conexões e multiplexa canais lógicos. Virtual hosts isolam namespaces, permissões e topologias. Em AMQP 0-9-1, publishers publicam em exchanges. A analisa tipo, routing key, e bindings para encaminhar a mensagem a uma ou mais filas, ou outras exchanges. Uma mensagem não roteada pode ser descartada ou devolvida ao publisher quando o modo mandatory é usado.
Exchanges direct comparam routing keys de forma exata; topic usam padrões hierárquicos; fanout distribuem para todos os bindings; usam propriedades da mensagem. Filas armazenam mensagens para consumidores. Durabilidade da fila, persistência da mensagem e replicação são conceitos diferentes: todos precisam estar coerentes com o requisito de sobrevivência a falhas.
Connections são recursos relativamente pesados; channels são usados para multiplexar operações. Abrir um channel por mensagem é antipadrão. Publishers e consumidores de longa duração precisam tratar reconexão, recuperação de topologia, confirms, acknowledgements e fluxo. O não substitui lógica de aplicação para deduplicação ou reconciliação.
RabbitMQ AMQP 0-9-1: publicação em e roteamento para filas
Figura 4 - Exchanges desacoplam publicação e filas por meio de regras de roteamento.
Tabela 4 - A exchange decide roteamento; a fila decide armazenamento e entrega aos consumidores.
Exchange
Regra
Uso comum
Direct
Routing key exata.
Comandos por categoria ou destino.
Topic
Padrões com palavras e curingas.
Eventos hierárquicos e assinaturas seletivas.
Fanout
Ignora routing key e distribui a todos.
Broadcast para várias filas.
Headers
Combina headers da mensagem.
Roteamento por múltiplos atributos.
31.10 RabbitMQ: acknowledgements, , quorum queues, e DLX
Consumer acknowledgements podem ser automáticos ou manuais. No modo manual, o consumidor confirma após concluir o trabalho, rejeita sem requeue quando a mensagem é inválida ou pede requeue quando a falha parece temporária. Requeue indiscriminado pode criar loop de redelivery. limita a quantidade de mensagens não confirmadas por consumidor e funciona como mecanismo de e distribuição de carga.
Publisher confirms informam que o assumiu responsabilidade pela publicação. Eles são independentes dos consumer acknowledgements. Para alto throughput, aplicações normalmente usam confirms assíncronos e correlacionam sequências, em vez de bloquear após cada mensagem. O uso de transações de channel é possível, mas costuma ter custo maior e não substitui transações de negócio.
Quorum queues são filas replicadas orientadas a segurança de dados e consenso. Classic queues permanecem úteis para casos específicos, mas não são a escolha de alta disponibilidade. e super oferecem retenção, e particionamento. Dead Letter Exchanges recebem mensagens expiradas, rejeitadas ou excedentes conforme políticas. Poison messages precisam de contagem de tentativas, quarentena e tratamento operacional, não apenas requeue infinito.
Tabela 5 - Recursos de confiabilidade precisam ser combinados com comportamento correto da aplicação.
Recurso
Resolve
Cuidado
Prefetch
Número de deliveries em voo.
Valor alto aumenta memória e trabalho perdido em falha.
Publisher confirm
Aceitação da publicação pelo broker.
Não confirma processamento do consumidor.
Manual ack
Conclusão do consumidor.
Ack cedo demais pode perder efeito.
Quorum queue
Replicação e segurança de dados.
Custo maior de disco, rede e quorum.
DLX/DLQ
Separação de mensagens não processáveis.
Precisa de ownership, alerta e reprocessamento.
31.11 AMQP 0-9-1 e AMQP 1.0
AMQP 0-9-1 é o modelo de protocolo amplamente associado ao RabbitMQ. Ele define exchanges, queues, bindings, channels e métodos como basic.publish, basic.consume e acknowledgements. AMQP 1.0 é um padrão OASIS diferente: define protocolo binário de wire, sistema de tipos, mensagens, connections, , links, flow control, e outcomes. Compartilhar o nome AMQP não torna as versões interoperáveis diretamente.
No AMQP 1.0, um link é unidirecional entre source e target e possui sender e receiver . Deliveries podem permanecer unsettled até que as partes concordem sobre o outcome. Créditos de link controlam fluxo. A especificação não obriga uma topologia de com exchanges e queues iguais às do RabbitMQ 0-9-1; produtos mapeiam conceitos do protocolo para suas próprias entidades.
Arquitetos precisam registrar versão e implementação explicitamente. Dizer apenas usamos AMQP é insuficiente. Uma biblioteca AMQP 1.0 não se conecta automaticamente a um que aceita apenas 0-9-1. Também variam autenticação SASL, endereçamento, , transactions e extensões do produto.
Figura 5 - AMQP 1.0 define uma pilha de protocolo diferente do modelo /queue do AMQP 0-9-1.
Tabela 6 - As duas famílias precisam ser documentadas separadamente.
Aspecto
AMQP 0-9-1
AMQP 1.0
Ênfase
Modelo de broker com exchanges e filas.
Protocolo de wire e mensageria em camadas.
Unidade lógica
Connection e channel.
Connection, session e link.
Roteamento
Exchange, routing key e bindings.
Source/target e semântica do produto.
Confirmação
Publisher confirms e consumer acks.
Settlement, delivery state e outcomes.
31.12 Jakarta Messaging/JMS
JMS foi a Java padronizada para mensageria corporativa e hoje faz parte de Jakarta Messaging. Ela oferece interfaces para criar conexões, produzir, consumir e ler mensagens por meio de um provider. A simplificada usa , enquanto o modelo clássico separa Connection, , MessageProducer e MessageConsumer. Destination representa Queue ou Topic.
JMS define modelos point-to-point e publish/subscribe, durable subscriptions, selectors, delivery mode, priority, expiration, modes e sessões transacionadas. Também integra-se a transações distribuídas por XA quando o provider e o ambiente suportam. XA pode ser necessário em legados, porém adiciona acoplamento e custo operacional; padrões como Outbox são frequentemente preferidos em microserviços.
JMS não define um único protocolo de rede nem garante que todos os providers implementem topologias idênticas. Um provider pode usar protocolo proprietário, AMQP ou outro transporte. Migrar de provider exige validar semântica de destino, redelivery, selectors, transações, temporary destinations, durable subscriptions e administração. O código Java pode compilar e ainda apresentar comportamento operacional diferente.
Figura 6 - Jakarta Messaging padroniza a da aplicação, enquanto o provider implementa conexão com o sistema de mensageria.
try (JMSContext context = connectionFactory.createContext()) {
Queue fila = context.createQueue("fila.pagamentos");
JMSProducer producer = context.createProducer();
producer.setProperty("eventType", "PagamentoCriado");
producer.send(fila, jsonPayload);
}
// O consumidor deve tratar redelivery e idempotência.
31.13 Padrões de integração com mensageria
Competing Consumers distribui trabalho entre instâncias. Publish/Subscribe entrega o mesmo evento a grupos diferentes. -Reply usa correlation ID e reply destination, mas pode recriar acoplamento síncrono sobre o . Dead Letter Channel isola mensagens não processáveis. com atraso deve diferenciar falha transitória de erro permanente e limitar tentativas.
Transactional Outbox grava alteração de negócio e evento na mesma transação local; um relay publica depois. Inbox registra mensagens processadas para deduplicação. Saga coordena transações locais e compensações. Event-Carried State Transfer leva dados suficientes no evento para reduzir chamadas síncronas. Check armazena grande fora do e transporta apenas referência segura.
Cada padrão tem custo. queues aumentam topologia e latência. DLQ sem processo operacional vira cemitério silencioso. -Reply pode saturar filas temporárias. Event-Carried State Transfer replica dados e exige governança de privacidade. O desenho deve incluir , monitoramento, ownership e procedimento de reprocessamento.
Tabela 7 - Padrões só são completos quando incluem operação e recuperação.
Padrão
Objetivo
Risco
Competing Consumers
Escalar processamento de tarefas.
Ordering e carga desigual.
Pub/Sub
Distribuir eventos para vários domínios.
Contratos e consumidores esquecidos.
Retry + DLQ
Separar falhas transitórias e permanentes.
Loops, acúmulo e reprocessamento inseguro.
Outbox + Inbox
Coordenar banco e publicação; deduplicar.
Latência e armazenamento operacional.
Request-Reply
Obter resposta assíncrona correlacionada.
Recriar dependência temporal.
31.14 Segurança, governança de e privacidade
Segurança começa no transporte e identidade. Kafka pode usar , , SASL e ACLs; RabbitMQ combina , mecanismos de autenticação, usuários, vhosts e permissões; providers JMS possuem controles próprios. Credenciais precisam de rotação, menor privilégio e separação por aplicação. Confiar em rede interna não substitui autenticação entre workloads.
Autorização deve limitar tópicos, grupos, exchanges, filas e operações administrativas. Um produtor comprometido não deve publicar em qualquer domínio, e um consumidor não deve ler eventos sensíveis sem necessidade. Em brokers multi-tenant, quotas, isolamento de namespace e proteção contra noisy neighbor são parte da segurança.
precisam de catálogo, owner, compatibilidade e classificação de dados. Eventos persistidos por dias ou meses ampliam impacto de vazamento e direito de retenção. Criptografia em repouso protege mídia, mas não impede consumidores autorizados de ver . Tokenização, minimização e separação de tópicos podem ser necessárias para LGPD e políticas corporativas.
31.15 Alta disponibilidade, capacidade e
Kafka distribui partições e réplicas entre brokers. RabbitMQ usa quorum queues, e outros mecanismos conforme o tipo de dado. Alta disponibilidade não é apenas ter três nós: é necessário distribuir falhas, testar eleição de líderes, verificar replicação, dimensionar disco e garantir que clientes descubram novos líderes ou reconectem corretamente.
Capacidade é determinada por taxa de entrada, taxa de saída, tamanho de mensagem, retenção, replicação e backlog máximo. Um fluxo que recebe 20 MB/s, replica três vezes e retém sete dias exige muito mais que a soma do de negócio. Compactação, índices, page , picos, rebalance e margem operacional entram no cálculo.
evita que produtores ou brokers sobrecarreguem consumidores. Kafka expressa pressão por lag, limites de e capacidade do consumidor. RabbitMQ usa , flow control e limites de fila. A aplicação precisa reduzir consumo, escalar ou rejeitar trabalho conscientemente. Acumular backlog sem apenas desloca a indisponibilidade para o futuro.
Planejamento de capacidade
Dimensione para o pior backlog aceitável, não apenas para a média. Inclua retenção, replicação, overhead, reprocessamento, manutenção e crescimento. O precisa sobreviver ao período em que consumidores estão degradados.
31.16 Observabilidade e
Observabilidade de mensageria precisa conectar produtor, e consumidor. Métricas essenciais incluem taxa de publicação, taxa de consumo, bytes, latência, erros, confirms pendentes, mensagens não confirmadas, lag, backlog, idade da mensagem mais antiga, redeliveries, DLQ, partições sem réplica sincronizada e utilização de disco. Uma métrica isolada raramente explica o problema.
Em Kafka, lag alto pode significar consumidor lento, partição quente, rebalance frequente, erro de processamento ou falta de capacidade. Em RabbitMQ, ready messages, unacked messages e taxa de acknowledgements ajudam a distinguir fila acumulada de consumidores travados. Em JMS, o diagnóstico também depende do provider e do modo de ou transação.
distribuídos devem propagar traceparent ou contexto equivalente em , mas o span assíncrono não deve fingir ser uma chamada síncrona longa. Correlation IDs, message IDs, causation IDs e timestamps permitem reconstruir cadeia de eventos. precisam evitar sensíveis e registrar decisões: published, confirmed, delivered, retried, dead-lettered e acknowledged.
Lag por partição, tempo de processamento e eventos de grupo.
Mensagens ready no RabbitMQ
Falta de consumidores ou erro de roteamento.
Consumer count, deliver rate e bindings.
Muitas unacked
Prefetch alto, consumidor travado ou ack tardio.
Unacked por channel e duração do processamento.
DLQ crescendo
Contrato inválido, dependência quebrada ou poison message.
Motivo, headers de retry e erro da aplicação.
Duplicatas
Retry, redelivery ou commit/ack fora de ordem.
IDs, offsets, redelivered flag e tabela Inbox.
31.17 Estudos de caso e laboratórios
Estudo de caso 1 - pagamentos: a registra a ordem e uma Outbox na mesma transação. Um relay publica PagamentoCriado em Kafka usando pagamentoId como chave. Serviços de fraude, notificação e conciliação usam grupos independentes. O serviço de fraude mantém ordering por pagamento e publica a decisão. Replays são executados em tópicos de saída isolados para não reenviar efeitos externos.
Estudo de caso 2 - tarefas operacionais: um sistema publica comandos em uma topic do RabbitMQ. Filas por capacidade recebem mensagens por routing key. Consumidores usam limitado, manual e com atraso. Depois do limite, mensagens seguem para DLQ com causa e contagem. Um processo operacional permite corrigir dado e republicar com idempotency key.
Estudo de caso 3 - legado Java: uma aplicação Jakarta EE usa JMS para publicar em um provider corporativo. A modernização preserva o contrato lógico, mas revisa transações XA, selectors, durable subscriptions e redelivery antes de migrar para outro . O time evita assumir que a mesma Java significa comportamento idêntico entre providers.
Laboratórios sugeridos
1) Publique mensagens em Kafka com duas chaves e observe partições e offsets. 2) Crie dois consumers no mesmo grupo e depois em grupos diferentes. 3) No RabbitMQ, configure direct, topic e fanout exchanges. 4) Teste manual , , nack, requeue e DLQ. 5) Implemente um consumidor idempotente com Inbox. 6) Compare uma JMS com o protocolo real usado pelo provider.
Resumo do capítulo
Mensageria desacopla produtores e consumidores no tempo e na capacidade, mas não elimina contrato, ownership nem falhas distribuídas. Filas, publish/subscribe e particionados possuem ciclos de vida diferentes. A escolha deve considerar retenção, , ordering, fan-out e natureza do trabalho.
Kafka organiza tópicos em partições persistentes e oferece consumer groups, offsets, retenção, compactação e transacionais dentro de fronteiras controladas. RabbitMQ enfatiza roteamento por exchanges, filas, acknowledgements, confirms, quorum queues, e topologias de entrega flexíveis. AMQP 0-9-1 e AMQP 1.0 são protocolos distintos, apesar do nome comum.
Jakarta Messaging/JMS padroniza a programação Java, não o nem o protocolo de wire. Em qualquer plataforma, confiabilidade real depende da combinação de confirmações, , ordering, , DLQ, observabilidade e capacidade. O melhor desenho explicita as janelas de falha e o procedimento de recuperação.
Próximo passo do curso
O próximo capítulo aprofunda observabilidade de e sistemas distribuídos, conectando , métricas e com OpenTelemetry. Os conceitos de correlation ID, lag, backlog, redelivery e causalidade estudados aqui serão essenciais.
Checklist de arquitetura e operação
O modelo foi escolhido conscientemente: fila, pub/sub, ou .
Contrato, owner, versão e classificação de dados da mensagem estão documentados.
Confirmação do produtor e do consumidor foram tratados separadamente.
A unidade de ordering e a chave de particionamento estão definidas.
Consumidores são idempotentes ou possuem estratégia explícita para duplicatas.
possuem limite, atraso e distinção entre falha transitória e permanente.
DLQ possui alerta, owner, procedimento de análise e reprocessamento seguro.
Retenção, e compactação foram avaliados contra privacidade e capacidade.
Permissões seguem menor privilégio para tópicos, grupos, vhosts, exchanges e filas.
Lag, backlog, idade da mensagem, confirms, unacked e DLQ são monitorados.
, eleição, reconexão e desastre foram testados.
Planos de capacidade incluem replicação, picos, manutenção e reprocessamento.
Exercícios
Diferencie fila tradicional, publish/subscribe e distribuído.
Explique por que não substitui consumer .
Descreva uma situação at-least-once e como torná-la idempotente.
Explique por que Kafka preserva ordem por partição e não globalmente.
Descreva a relação entre tópico, partição, e .
Compare direct, topic, fanout e exchanges no RabbitMQ.
Diferencie , classic queue e .
Explique por que AMQP 0-9-1 e AMQP 1.0 não devem ser tratados como a mesma coisa.
Descreva o papel de , Destination, Producer e Consumer.
Projete e DLQ para um consumidor que chama um serviço externo.
Liste métricas para diagnosticar lag alto no Kafka e unacked alto no RabbitMQ.
Proponha uma estratégia de que não repita efeitos externos perigosos.
Glossário
Tabela 9 - Vocabulário essencial do capítulo.
Termo
Definição
Acknowledgement
Confirmação do consumidor ao broker sobre o processamento de uma entrega.
Binding
Regra que conecta exchange a fila, stream ou outra exchange no RabbitMQ.
Broker
Intermediário que recebe, armazena, roteia e entrega mensagens.
Consumer group
Conjunto de consumidores que divide partições de um tópico Kafka.
Dead Letter Queue
Destino para mensagens que não puderam ser processadas normalmente.
Delivery semantics
Garantia observada como at-most-once, at-least-once ou exatamente uma vez em contexto específico.
Exchange
Entidade RabbitMQ que roteia publicações conforme tipo e bindings.
Idempotência
Propriedade de repetir uma operação sem alterar o resultado final além da primeira execução.
JMSContext
Interface principal da API simplificada Jakarta Messaging.
KRaft
Modo de metadata e quorum de controladores do Kafka.
Offset
Posição de um registro em uma partição ou stream.
Partition
Subdivisão ordenada e escalável de um tópico Kafka.
Prefetch
Limite de mensagens não confirmadas entregues a um consumidor RabbitMQ.
Publisher confirm
Confirmação do broker ao produtor sobre a publicação.
Quorum queue
Fila replicada do RabbitMQ orientada a segurança de dados.
Settlement
Acordo sobre o estado final de uma delivery em AMQP 1.0.
Tombstone
Registro com valor nulo usado para remoção em logs compactados.
RabbitMQ Documentation - queues, exchanges, consumers, publisher confirms, quorum queues, , e dead lettering.
OASIS. Advanced Message Queuing Protocol (AMQP) Version 1.0.
Jakarta EE. Jakarta Messaging 3.1 Specification and Documentation.
Enterprise Integration Patterns - Message Channel, Competing Consumers, Publish-Subscribe, Dead Letter Channel e -Reply.
CloudEvents Specification - envelope padronizado para eventos.
OpenTelemetry Specification - propagação de contexto em mensageria.
e recomendações corporativas de segurança para brokers, credenciais e dados persistidos.
Nota de atualização
Versões de Kafka, RabbitMQ, bibliotecas e providers JMS evoluem. Antes de adotar configurações, valide a documentação oficial da versão implantada, especialmente para , consumer groups, quorum queues, , AMQP 1.0 e integração transacional.