SQS vs SNS vs EventBridge: Kdy použít kterou službu AWS
Tři služby AWS, tři různé filozofie. SQS je fronta: zaručuje, že každá zpráva zpracovává pouze jeden spotřebitel. SNS je to fanouškovská hospoda/sub: doruč to stejná zpráva všem účastníkům paralelně. EventBridge je to chytrý router: směruje události na základě obsahu. Výběr špatné služby znamená křehké architektury, vysoké náklady a neočekávaně ztracené nebo duplicitní zprávy.
Amazon SQS: Fronta zpráv
Amazon Simple Queue Service (SQS) je spravovaná fronta zpráv: producenti posílají zprávy do fronty, spotřebitelé je získávají prostřednictvím dotazování. Základní sémantika je point-to-point: Zpráva ve frontě čte jej vždy jeden spotřebitel (první, kdo si jej vezme, jej „schová“ před ostatními přes časový limit viditelnosti).
Standardní fronta vs fronta FIFO
SQS nabízí dva režimy:
- Standardní fronta: Neomezená propustnost, alespoň jedno doručení (možné duplikáty), objednání s maximální snahou (není zaručeno). Pro případy velkoobjemového použití kde jsou duplikáty zvládnutelné na straně spotřebitele.
-
Fronta FIFO: přesně jednou doručení (automatická deduplikace přes
MessageDeduplicationId), zaručené třídění pro skupina zpráv, propustnost omezena na 3 000 msg/s na požadavek (s dávkováním). Pro případy použití, kdy jsou objednávky a duplikáty kritické (např. finanční transakce).
// SQS Producer Java con AWS SDK v2
import software.amazon.awssdk.services.sqs.*;
import software.amazon.awssdk.services.sqs.model.*;
public class SqsProducer {
private final SqsClient sqsClient = SqsClient.builder()
.region(Region.EU_WEST_1)
.build();
// Standard Queue: invio semplice
public void sendToStandardQueue(String queueUrl, String messageBody) {
SendMessageResponse response = sqsClient.sendMessage(
SendMessageRequest.builder()
.queueUrl(queueUrl)
.messageBody(messageBody)
// Delay di consegna (0-900 secondi)
.delaySeconds(0)
// Attributi del messaggio per filtraggio (SNS subscription filter)
.messageAttributes(Map.of(
"eventType", MessageAttributeValue.builder()
.stringValue("OrdineCreato")
.dataType("String")
.build()
))
.build()
);
System.out.println("Messaggio inviato: " + response.messageId());
}
// FIFO Queue: richiede MessageGroupId e MessageDeduplicationId
public void sendToFifoQueue(String queueUrl, String ordineId, String payload) {
sqsClient.sendMessage(
SendMessageRequest.builder()
.queueUrl(queueUrl) // url deve terminare in .fifo
.messageBody(payload)
// Group: tutti i messaggi dello stesso ordine vengono elaborati in ordine
.messageGroupId("ordine-" + ordineId)
// Deduplication: prevenzione duplicati (valido 5 minuti)
.messageDeduplicationId(ordineId + "-" + System.currentTimeMillis())
.build()
);
}
}
Zákazník SQS: Časový limit dotazování a viditelnosti
// SQS Consumer con Long Polling e gestione DLQ
public class SqsConsumer {
private final SqsClient sqsClient = SqsClient.builder()
.region(Region.EU_WEST_1).build();
public void poll(String queueUrl) {
while (true) {
// Long polling: aspetta fino a 20 secondi per nuovi messaggi
// Riduce le chiamate vuote (e i costi) rispetto al short polling
ReceiveMessageResponse response = sqsClient.receiveMessage(
ReceiveMessageRequest.builder()
.queueUrl(queueUrl)
.maxNumberOfMessages(10) // max 10 per chiamata
.waitTimeSeconds(20) // long polling
.visibilityTimeout(30) // 30s per elaborare
.messageAttributeNames("All")
.build()
);
for (Message message : response.messages()) {
try {
processMessage(message.body());
// Successo: elimina dalla coda
sqsClient.deleteMessage(
DeleteMessageRequest.builder()
.queueUrl(queueUrl)
.receiptHandle(message.receiptHandle())
.build()
);
} catch (Exception e) {
// Non eliminare: SQS rirenderà visibile il messaggio
// dopo il visibility timeout. Dopo maxReceiveCount tentativi
// finisce nella DLQ configurata
System.err.println("Errore, il messaggio tornera visibile: " + e.getMessage());
}
}
}
}
}
Amazon SNS: Fan-Out Pub/Sub
Amazon Simple Notification Service (SNS) implementuje vzor zveřejnit/přihlásit se k odběru: producent odešle zprávu a Témata SNSa SNS je doručuje paralelně všem členové (odběratel). Téma SNS může mít tisíce odběratelů: Lambda, SQS, HTTP endpoint, e-mail, SMS, mobilní push.
Vzor SNS + SQS (SNS Fan Out) je jedním z nejběžnějších vzorů v architekturách AWS: SNS doručuje stejnou událost do více front SQS paralelně, a každá fronta obsluhuje jiného spotřebitele (jinou mikroslužbu).
# SNS + SQS Fan-Out: un evento raggiunge 3 servizi in parallelo
# Struttura:
# SNS Topic "ordini-topic"
# |--- SQS "inventario-queue" --- Lambda inventario
# |--- SQS "pagamenti-queue" --- Lambda pagamenti
# |--- SQS "notifiche-queue" --- Lambda notifiche email
# Terraform
resource "aws_sns_topic" "ordini" {
name = "ordini-topic"
}
resource "aws_sqs_queue" "inventario" {
name = "inventario-queue"
visibility_timeout_seconds = 60
redrive_policy = jsonencode({
deadLetterTargetArn = aws_sqs_queue.inventario_dlq.arn
maxReceiveCount = 3
})
}
resource "aws_sns_topic_subscription" "ordini_inventario" {
topic_arn = aws_sns_topic.ordini.arn
protocol = "sqs"
endpoint = aws_sqs_queue.inventario.arn
# Filter policy: questa subscription riceve SOLO OrdineCreato
filter_policy = jsonencode({
eventType = ["OrdineCreato"]
})
}
// SNS Publisher Java
import software.amazon.awssdk.services.sns.*;
import software.amazon.awssdk.services.sns.model.*;
public class SnsPublisher {
private final SnsClient snsClient = SnsClient.builder()
.region(Region.EU_WEST_1).build();
public void publishOrdineCreato(String topicArn, OrdineCreato event) throws Exception {
String messageJson = new ObjectMapper().writeValueAsString(event);
PublishResponse response = snsClient.publish(
PublishRequest.builder()
.topicArn(topicArn)
.message(messageJson)
// Message attributes per subscription filter
.messageAttributes(Map.of(
"eventType", MessageAttributeValue.builder()
.stringValue("OrdineCreato")
.dataType("String")
.build()
))
// Subject visibile solo nelle email
.subject("Nuovo ordine: " + event.getOrdineId())
.build()
);
System.out.println("SNS Message ID: " + response.messageId());
}
}
Kompletní srovnání
| Charakteristický | SQS | SNS | EventBridge |
|---|---|---|---|
| Model | Point-to-point (fronta) | Fan-out (hospoda/sub) | Směrování založené na obsahu |
| Příjemci | 1 spotřebitel najednou | Všechny registrovány paralelně | Cíle podle pravidla (1-5) |
| Filtr | Nikdo (bere všechno) | Atributy zprávy (omezené) | Vzor události v libovolném poli JSON |
| Řazení | Garantovaná FIFO (fronta FIFO) | No | No |
| Deduplikace | Ano (fronta FIFO) | No | No |
| Max. propustnost | Neomezené (standardní) | Neomezený | 10 milionů událostí/s na region |
| Latence | Milisekundy (dotazování) | < 1 s (stisk) | < 500 ms |
| Registr schémat | No | No | Ano (integrované) |
| Archiv/Přehrání události | No | No | Si |
| Integrace partnerů SaaS | No | No | Ano (35 a více partnerů) |
| Cena za milion zpráv | ~0,40 $ | ~0,50 $ | ~1,00 $ |
Průvodce rozhodováním: Kdy použít který
Použijte SQS, když:
- musíte vyvažování zátěže mezi více spotřebiteli stejného typu (např. 5 lambd zpracovávajících stejnou frontu)
- Zpráva musí být propracovaná přesně jednou (fronta FIFO)
- musíte protitlak: Zprávy se hromadí ve frontě, když jsou spotřebitelé pomalí
- Chcete? zpoždění dodávky (až 15 minut na jednu zprávu)
- Integrujete starší systémy, které používají tradiční model fronty
Použijte SNS, když:
- Stejná událost musí dosáhnout více systémů paralelně (vějířovitý vzor)
- Musíte poslat oznámení (e-mail, SMS, mobilní push, HTTP webhook)
- Kombinujte SNS + SQS, abyste měli pro každého spotřebitele jak rozvětvení, tak vyrovnávací paměť
EventBridge použijte, když:
- musíte inteligentní směrování na základě obsahu užitečného zatížení
- Integrujte se s služby AWS (EC2, S3, RDS) popř partneři SaaS (Zendesk, Shopify, Stripe)
- Chceš to Registr schémat a řízení systému
- musíte Archiv událostí a přehrávání
- Sestavte a autobus pro firemní akce s centralizovaným směrováním
Vzor SNS + SQS + Lambda: Kompletní sada
# Architettura tipica per un microservizio event-driven su AWS
#
# Client HTTP
# |
# v
# API Gateway / Lambda "ordini-api"
# | pubblica su
# v
# SNS Topic "ordini-events"
# |-- filtra "OrdineCreato" --> SQS "inventario-queue" --> Lambda "inventario-handler"
# |-- filtra "OrdineCreato" --> SQS "notifiche-queue" --> Lambda "email-notifier"
# |-- tutti i tipi --> SQS "audit-queue" --> Lambda "audit-logger"
#
# Ogni SQS ha la sua DLQ per messaggi non elaborabili
# Le Lambda usano le SQS come event source (SQS trigger)
# Configurazione Lambda con SQS trigger
resource "aws_lambda_event_source_mapping" "inventario" {
event_source_arn = aws_sqs_queue.inventario.arn
function_name = aws_lambda_function.inventario_handler.arn
batch_size = 10 # processa 10 messaggi alla volta
enabled = true
# Bisection on error: in caso di errore batch, divide il batch a meta
# per identificare il messaggio problematico (evita il poison pill)
bisect_batch_on_function_error = true
# Finestra di aggregazione (utile per batch processing)
maximum_batching_window_in_seconds = 5
}
EventBridge + SQS: to nejlepší z obou světů
V mnoha architekturách se EventBridge a SQS doplňují: EventBridge zajišťuje inteligentní směrování, SQS zajišťuje ukládání do vyrovnávací paměti a vyrovnávání zátěže. Událost dorazí na EventBridge, je směrována do příslušné fronty SQS, a spotřebitelská Lambda jej zpracuje z fronty s opakováním a DLQ.
# EventBridge --> SQS (con transform di input opzionale)
resource "aws_cloudwatch_event_target" "ordini_to_sqs" {
rule = aws_cloudwatch_event_rule.ordini_vip.name
event_bus_name = aws_cloudwatch_event_bus.mioapp.name
arn = aws_sqs_queue.vip_orders.arn
# Input transformer: ristruttura il payload prima di inviarlo a SQS
# Utile per estrarre solo i campi necessari
input_transformer {
input_paths = {
ordineId = "$.detail.ordineId"
clienteId = "$.detail.clienteId"
totale = "$.detail.totale"
}
input_template = <<-EOF
{
"ordineId": "<ordineId>",
"clienteId": "<clienteId>",
"totale": "<totale>",
"processato_da": "eventbridge-vip-rule"
}
EOF
}
}
Další kroky v sérii
- Článek 8 – Fronta nedoručených dopisů a odolnost: správná konfigurace DLQ pro SQS, SNS a EventBridge je zásadní pro zamezení ztráty zpráv. Časový limit viditelnosti, maxReceiveCount a vzor opětovného zpracování.
Propojení s ostatními sériemi
- AWS EventBridge (článek 6): hloubková analýza vzorců událostí, registr schémat a archiv událostí, všechny podrobnosti o konfiguraci EventBridge.
- Apache Kafka (řada 38): pro místní použití nebo případy použití s velmi vysokou propustností (>10 milionů msg/s), Kafka je lepší než SQS/SNS. Výběr závisí na poskytovateli cloudu, propustností a potřebou přehrávání událostí.







