SQS vs SNS vs EventBridge: Hangi AWS Hizmeti Ne Zaman Kullanılmalı
Üç AWS hizmeti, üç farklı felsefe. SQS bir kuyruktur: her mesajın tek bir tüketici tarafından işlenir. SNS bu bir yayınevi pub/sub: teslim edin Aynı mesaj tüm abonelere paralel olarak gönderilir. Etkinlik Köprüsü bu akıllı bir yönlendirici: Olayları içeriğe göre yönlendirir. Yanlış hizmetin seçilmesi kırılgan mimariler anlamına gelir, yüksek maliyetler ve beklenmedik şekilde kaybolan veya kopyalanan mesajlar.
Amazon SQS: Mesaj Kuyruğu
Amazon Basit Kuyruk Hizmeti (SQS) yönetilen bir mesaj kuyruğu: üreticiler kuyruğa mesaj gönderir, tüketiciler ise bunları yoklama yoluyla alır. Temel anlambilim şunlardır: noktadan noktaya: Kuyruktaki bir mesaj her seferinde bir tüketici tarafından okunur (ilk alan onu diğerlerinden "gizler" aracılığıyla görünürlük zaman aşımı).
Standart Kuyruk ve FIFO Kuyruğu
SQS iki mod sunar:
- Standart Sıra: Sınırsız üretim, en az bir kez teslimat (kopyalama mümkündür), en iyi çabayla sipariş verme (garanti edilmez). Yüksek hacimli kullanım durumları için kopyaların tüketici tarafında yönetilebilir olduğu yer.
-
FIFO Sırası: tam olarak bir kez teslimat (üzerinden otomatik veri tekilleştirme)
MessageDeduplicationId), garantili sıralama mesaj grubu, aktarım hızı istek başına 3.000 msg/s ile sınırlıdır (toplama ile). Sipariş vermenin ve kopyaların kritik olduğu durumlarda (ör. finansal işlemler) kullanım için.
// 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()
);
}
}
SQS Tüketicisi: Yoklama ve Görünürlük Zaman Aşımı
// 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 Basit Bildirim Hizmeti (SNS) deseni uygular yayınla/abone ol: Bir yapımcı bir kişiye mesaj gönderir SNS konularıve SNS bunu herkese paralel olarak sunuyor üyeler (abone). Bir SNS konusunun binlerce abonesi olabilir: Lambda, SQS, HTTP uç noktası, e-posta, SMS, mobil push.
SNS + SQS modeli (SNS Fan Çıkışı) en yaygın kalıplardan biridir AWS mimarilerinde: SNS aynı olayı paralel olarak birden fazla SQS kuyruğuna iletir, ve her sıra farklı bir tüketiciye (farklı bir mikro hizmet) hizmet eder.
# 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());
}
}
Tam Karşılaştırma
| karakteristik | SQS | SNS | Etkinlik Köprüsü |
|---|---|---|---|
| Modeli | Noktadan noktaya (kuyruk) | Yayılma (pub/sub) | İçerik tabanlı yönlendirme |
| Alıcılar | Aynı anda 1 tüketici | Hepsi paralel kayıtlı | Kurala göre hedefler (1-5) |
| Filtre | Hiç kimse (her şeyi alır) | Mesaj özellikleri (sınırlı) | Herhangi bir JSON alanındaki olay modeli |
| Sıralama | Garantili FIFO (FIFO kuyruğu) | No | No |
| Tekilleştirme | Evet (FIFO kuyruğu) | No | No |
| Maks. verim | Sınırsız (Standart) | Sınırsız | Bölge başına 10 milyon olay/s |
| Gecikme | Milisaniye (oylama) | < 1s (itme) | < 500ms |
| Şema Kaydı | No | No | Evet (entegre) |
| Etkinlik Arşivi/Tekrar Oynatma | No | No | Si |
| İş ortağı entegrasyonu SaaS | No | No | Evet (35+ ortak) |
| Milyon mesaj başına maliyet | ~0,40$ | ~0,50$ | ~1,00$ |
Karar Kılavuzu: Hangisi Ne Zaman Kullanılmalı
Şu durumlarda SQS'yi kullanın:
- Gerek yük dengeleme aynı türden birden fazla tüketici arasında (örneğin, aynı kuyruğu işleyen 5 Lambda)
- Mesaj detaylandırılmalı tam olarak bir kez (FIFO kuyruğu)
- Gerek karşı basınç: Tüketiciler yavaş olduğunda mesajlar kuyrukta birikir
- istiyor musun teslimat gecikmesi (tek mesaj başına en fazla 15 dakika)
- Geleneksel kuyruk modelini kullanan eski sistemleri entegre ediyorsunuz
SNS'yi şu durumlarda kullanın:
- Aynı olayın ulaşması gerekiyor paralel olarak birden fazla sistem (yayma deseni)
- Göndermeniz gerekiyor bildirimler (e-posta, SMS, mobil push, HTTP webhook)
- Her tüketici için hem yayma hem de ara belleğe alma sağlamak için SNS + SQS'yi birleştirin
EventBridge'i şu durumlarda kullanın:
- Gerek akıllı yönlendirme yükün içeriğine bağlı olarak
- Şununla entegre et: AWS hizmetleri (EC2, S3, RDS) veya SaaS ortakları (Zendesk, Shopify, Stripe)
- Sen onu istiyorsun Şema Kaydı ve plan yönetimi
- Gerek Etkinlik Arşivi ve Tekrarı
- Bir inşa et kurumsal etkinlik otobüsü merkezi yönlendirme ile
SNS + SQS + Lambda Modeli: Eksiksiz Yığın
# 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: Her İki Dünyanın En İyisi
Birçok mimaride EventBridge ve SQS tamamlayıcıdır: EventBridge akıllı yönlendirmeyi yapar, SQS ara belleğe alma ve yük dengelemeyi yapar. EventBridge'e bir olay geldiğinde uygun SQS kuyruğuna yönlendirilir, ve tüketici Lambda bunu yeniden deneme ve DLQ ile kuyruktan işler.
# 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
}
}
Serideki Sonraki Adımlar
- Madde 8 – Teslim Edilmeyen Mektup Sırası ve Esneklik: doğru konfigürasyon SQS, SNS ve EventBridge için DLQ'nun kullanılması mesaj kaybını önlemek açısından kritik öneme sahiptir. Görünürlük zaman aşımı, maxReceiveCount ve yeniden işleme modeli.
Diğer Serilerle Bağlantı
- AWS EventBridge (Madde 6): olay kalıplarının derinlemesine analizi, şema kaydı ve olay arşivi, tüm EventBridge yapılandırma ayrıntıları.
- Apaçi Kafka (Seri 38): şirket içi veya çok yüksek verimli kullanım durumları için (>10 milyon msg/s), Kafka SQS/SNS'den üstündür. Seçim bulut sağlayıcısına bağlıdır. verimlilik ve olayın tekrar oynatılması ihtiyacına göre.







