05 - AWS SQS-SNS (Mensageria gerenciada)
video: https://youtu.be/... no frontmatter da nota.AWS SQS-SNS (Mensageria gerenciada)
O SQS (Simple Queue Service) e o SNS (Simple Notification Service) formam o par de mensageria gerenciada da AWS, presente em praticamente toda arquitetura de eventos na plataforma. O SQS entrega filas para desacoplar produtores e consumidores, com durabilidade embutida, escala praticamente sem teto e administração zero; o SNS entrega tópicos de publicação e assinatura com fanout para filas, funções, endpoints HTTP e e-mail. Juntos cobrem os dois blocos fundamentais de comunicação assíncrona: fila de trabalho a processar e distribuição de eventos a quem se interessou. A escala do serviço em produção é consolidada, com fila e tópico sobrevivendo a picos de milhões de mensagens por segundo sem provisionamento, e o modelo de cobrança por requisição alinha custo ao volume real. Entender as garantias de entrega, o ciclo de visibilidade, as filas de mensagens mortas e os filtros de assinatura é o que separa um desenho de eventos robusto de um que perde ou duplica mensagens silenciosamente.
Fila e tópico: blocos complementares
A fila resolve comunicação ponto a ponto: um produtor enfileira trabalho, e um pool de consumidores processa em ritmo próprio, absorvendo picos e tornando falhas de downstream tolerantes, pois o trabalho permanece na fila até ser processado. O tópico resolve distribuição um-para-muitos: um produtor publica um evento, e todos os assinantes registrados recebem uma cópia, sem que o publicador conheça os destinatários.
| Bloco | Padrão | Consumidores | Retenção |
|---|---|---|---|
| SQS | Ponto a ponto, competição | Uma mensagem é entregue a um consumidor | Até 14 dias |
| SNS | Publicar e assinar | Cada assinante recebe uma cópia | Entrega imediata |
A escolha segue a pergunta: o destino é um único processador, mesmo que escalado em réplicas, ou um conjunto de interessados distintos? Trabalho a executar pede fila; notificação de que algo aconteceu pede tópico. Arquiteturas maduras combinam os dois, como detalhado adiante no padrão SNS mais SQS.
Ambos os serviços expõem atributos por fila e por tópico que valem revisão desde o início: tamanho máximo de mensagem, retenção, delay de entrega, tempo de espera de long polling e política de redrive no SQS, e políticas de retry por protocolo no SNS. Deixar esses valores como padrão raramente atende um sistema de produção sem ajuste.
SQS standard versus FIFO
A fila standard é a opção padrão, com throughput praticamente ilimitado, entrega at-least-once e nenhuma garantia de ordenação; mensagens podem chegar duplicadas e fora de ordem, e a aplicação precisa ser idempotente. A fila FIFO garante ordenação e deduplicação dentro de grupos de mensagens, com throughput limitado por fila e por grupo, e é obrigatória quando a ordem é requisito do domínio, como sequência de eventos de um mesmo pedido.
| Característica | Standard | FIFO |
|---|---|---|
| Throughput | Virtualmente ilimitado | Limitado por fila e por grupo de mensagens |
| Entrega | At-least-once, com duplicatas | Exactly-once de processamento dentro do grupo |
| Ordem | Não garantida | Garantida dentro do message group |
| Deduplicação | Pela aplicação | Nativa por deduplication ID e escopo |
| Custo | Menor | Mais alto |
| Caso típico | Processamento paralelo de trabalho | Pedidos, eventos por cliente, estado sequencial |
A decisão prática: comece por standard e desenhe idempotência desde o primeiro consumidor; vá para FIFO quando a ordem for requisito real do domínio, modelando grupos de forma que a paralelização dentro dos grupos compense o limite de throughput. Um erro clássico é usar FIFO com um único grupo e transformar a fila em gargalo serial.
Visibility timeout e ciclo de consumo
O ciclo de consumo do SQS é baseado em visibilidade, e não em acknowledge tradicional de broker: o consumidor recebe a mensagem com long polling, e a mensagem fica invisível para os demais pelo período do visibility timeout enquanto é processada. Se o processamento termina e o consumidor deleta a mensagem, o ciclo fecha; se o consumidor falha e o timeout expira, a mensagem volta a ficar visível e é entregue novamente, o que materializa a entrega at-least-once.
# Fila com long polling e timeout de visibilidade alinhado ao processamento
aws sqs create-queue --queue-name pedidos-processamento \
--attributes '{
"VisibilityTimeout": "300",
"ReceiveMessageWaitTimeSeconds": "20",
"MessageRetentionPeriod": "345600",
"RedrivePolicy": "{\"deadLetterTargetArn\":\"arn:aws:sqs:sa-east-1:...:pedidos-dlq\",\"maxReceiveCount\":5}"
}'
# Consumo com long polling reduz chamadas vazias e custo
aws sqs receive-message --queue-url https://sqs.sa-east-1.amazonaws.com/.../pedidos-processamento \
--max-number-of-messages 10 --wait-time-seconds 20
# Confirmação: apenas após processar com sucesso
aws sqs delete-message --queue-url https://sqs.sa-east-1.amazonaws.com/.../pedidos-processamento \
--receipt-handle "AQEBwJnK..."
O visibility timeout deve ser maior que o p-99 do tempo de processamento, e o SQS oferece extensão de visibilidade para processamentos longos. Recebimentos com wait time alto de long polling reduzem chamadas vazias, que também são cobradas, e o redrive policy encaminha à DLQ após o máximo de recebimentos configurado.
Dead letter queue: diagnóstico de mensagens problemáticas
A DLQ recebe mensagens que ultrapassam o limite de tentativas, e é a base do diagnóstico de falhas persistentes. Em produção, a DLQ tem alarme de profundidade: qualquer mensagem ali é sinal de bug, payload problemático ou dependência caída por tempo suficiente para esgotar tentativas. Consumir e analisar a DLQ, com reprocessamento controlado por redrive permitindo devolver mensagens à fila principal após correção, faz parte do runbook do serviço.
No FIFO, o comportamento da DLQ exige atenção adicional: mensagens mortas podem atrasar o grupo de mensagens, pois a fila preserva ordenação, e desenhar limites de tentativa menores e alertas mais sensíveis evita que um payload problemático trave o fluxo de um cliente.
O mapeamento de falhas também merece atenção: distinguir erros retratáveis, como timeouts transitórios, de erros permanentes, como payload inválido, evita retratar por tentativas o que só será resolvido com intervenção. Algumas arquiteturas usam DLQ intermediária ou roteiam erros permanentes direto para um bucket de auditoria com o payload e o motivo.
SNS: tópicos, fanout e filtros de assinatura
O SNS publica mensagens em tópicos e entrega a cada assinante: filas SQS, funções Lambda, endpoints HTTP, SMS e e-mail, com tentativas automáticas e políticas de retry por protocolo. Os filtros de assinatura são a peça que transforma o tópico em um barramento de eventos de verdade: cada assinatura declara um JSON filter policy sobre atributos da mensagem, e o SNS entrega apenas o que casa com o filtro.
# Publica evento com atributos para filtragem
aws sns publish \
--topic-arn arn:aws:sns:sa-east-1:...:pedidos-eventos \
--message '{"pedidoId": "8842", "status": "PAGO"}' \
--message-attributes '{
"tipoEvento": {"DataType": "String", "StringValue": "PedidoPago"},
"regiao": {"DataType": "String", "StringValue": "sudeste"}
}'
# Assinatura de fila apenas para eventos de pagamento no sudeste
aws sns subscribe \
--topic-arn arn:aws:sns:sa-east-1:...:pedidos-eventos \
--protocol sqs \
--notification-endpoint arn:aws:sqs:sa-east-1:...:estoque-baixa \
--attributes '{
"FilterPolicy": "{\"tipoEvento\":[\"PedidoPago\"],\"regiao\":[\"sudeste\"]}"
}'
Com filtros, um único tópico serve múltiplos domínios consumindo recortes distintos, sem que o publicador conheça os interessados. A modelagem dos atributos do evento vira contrato público, e mudanças nela seguem disciplina de versionamento, pois consumidores de outros times dependem da semântica.
O SNS também oferece deduplicação por conteúdo para tópicos FIFO, garantindo que republicações idênticas em janela curta não multipliquem entregas, e assinaturas de fila FIFO preservam a ordenação ponta a ponta quando o domínio exige sequência com fanout.
O padrão SNS mais SQS em arquitetura orientada a eventos
A combinação resolve a tensão central de distribuição de eventos: o SNS entrega a todos os interessados no momento da publicação, e o SQS guarda a cópia para cada consumidor processar no próprio ritmo, com retry, visibilidade e DLQ próprios. O publicador fala com um tópico; cada domínio assina com filtro e consome de uma fila dedicada, e a falha ou lentidão de um consumidor não afeta os demais.
| Papel na arquitetura | Componente | Benefício obtido |
|---|---|---|
| Publicação única de evento | Tópico SNS | Produtor desacoplado de todos os consumidores |
| Recorte por interesse | Filter policy | Cada domínio recebe só o que precisa |
| Absorção de pico e retry | Fila SQS por consumidor | Ritmo próprio, tolerância a falha downstream |
| Diagnóstico de falhas | DLQ por fila | Mensagens problemáticas isoladas e audíveis |
| Proteção do produtor | Entrega assíncrona | Escrita não espera consumidores |
Esse padrão é o equivalente serverless do barramento de eventos e cobre a maioria dos casos onde times avaliariam Kafka com simplicidade operacional muito maior, ao preço de não oferecer replay e streaming persistente com ordenação global, o que é exatamente o papel do Kinesis ou MSK quando o requisito existe.
Comparação com alternativas de mensageria
| Critério | SQS + SNS | Kafka (MSK) | RabbitMQ |
|---|---|---|---|
| Modelo | Fila e pub/sub gerenciados | Log de eventos distribuído | Broker de fila tradicional |
| Replay de mensagens | Não, consumo deleta | Sim, por offset e retenção | Limitado |
| Ordenação | FIFO por grupo | Por partição | Por fila |
| Operação | Nenhuma | Cluster, partições, consumidores | Cluster administrado pelo time |
| Custo em volume baixo | Baixíssimo | Relativamente alto | Médio |
| Caso ideal | Desacoplamento de serviços | Streaming, analytics, replay | Roteamento complexo de mensagens |
A regra de decisão é honesta sobre requisitos: sem necessidade de replay e de janela de retenção para reconstrução de estado, SQS e SNS entregam o essencial com custo operacional próximo de zero, e a adoção de Kafka se justifica por requisitos de streaming, e não por moda arquitetural.
Erros comuns e boas práticas
- Escrever consumidores não idempotentes contra filas standard e quebrar com duplicatas entregues; trate idempotência como requisito de desenho.
- Configurar visibility timeout menor que o processamento e gerar processamento duplicado concorrente; meça o p-99 e deixe folga.
- Criar DLQ sem alarme de profundidade; mensagens mortas sem monitoramento viram buraco negro de dados.
- Usar FIFO com um único message group para todo o volume, serializando a fila; modele grupos pela granularidade de ordenação real.
- Enviar payloads gigantes no corpo da mensagem; o padrão claim check guarda a carga em S3 e trafega apenas a referência.
- Assinar tópicos sem filtros e consumir tudo, desperdiçando processamento; declare filter policies explícitas.
- Deixar filas e tópicos sem políticas de acesso restritivas; restrinja produtor e consumidor por ARN e audite com Access Analyzer.
- Tratar e-mail e SMS como caminho crítico de entrega sem modelo de confirmidade; prefira SQS e Lambda para integração confiável.
- Armazenar segredos ou dados sensíveis sem criptografia no corpo da mensagem; habilite SSE com KMS e minimize o que trafega.
- Ignorar o teto de 256 KB por mensagem e sofrer falhas em payloads grandes; adote o padrão claim check desde o desenho.
Como prática consolidada, padronize envelopes de evento com schema versionado, declare idempotência no desenho do consumidor, configure DLQ com alarme em toda fila de produção e prefira o padrão SNS mais SQS como espinha dorsal de eventos, elevando para MSK ou Kinesis apenas quando replay, retenção e throughput de streaming forem requisitos explícitos do domínio.