AWS SQS Mesaj Kuyruğu Kurulumu ve Yönetimi
Mesaj kuyruklama sistemleri, modern mikroservis mimarilerinin belkemiğini oluşturuyor. Uygulamalar arasındaki iletişimi asenkron hale getirmek, bağımlılıkları azaltmak ve sistem dayanıklılığını artırmak istediğinizde AWS SQS tam olarak aradığınız araç. Ben de bu yazıda sıfırdan bir SQS kuyruğu kurmanın tüm adımlarını, gerçek dünya senaryolarıyla birlikte ele alacağım.
AWS SQS Nedir ve Neden Kullanılır
Amazon Simple Queue Service, tamamen yönetilen bir mesaj kuyruklama servisi. Kendi RabbitMQ ya da Kafka kurulumunuzu yönetmek yerine AWS’nin altyapısını kullanıyorsunuz. Sunucu bakımı yok, ölçeklendirme derdi yok, yüksek erişilebilirlik kutudan çıkıyor.
Pratik bir senaryo düşünelim: E-ticaret sitenizde kullanıcı sipariş verdiğinde aynı anda e-posta gönderme, fatura oluşturma, stok güncelleme ve kargo bildirimi işlemlerini yapmanız gerekiyor. Tüm bunları senkron yapmak hem yavaşlatır hem de bir servis çöktüğünde siparişin tamamını mahvedebilir. SQS ile sipariş servisi kuyruğa mesajı bırakır, diğer servisler sırayla işler. Biri çökse bile mesaj kuyrukta bekler.
SQS’in iki ana kuyruğu türü vardır:
- Standard Queue: En yüksek throughput, en az bir kez teslim garantisi, mesaj sırası garanti edilmez
- FIFO Queue: Kesin sıra garantisi, tam olarak bir kez işleme, saniyede 300 mesaj limiti (batch ile 3000)
Ön Hazırlık: AWS CLI Kurulumu ve Yapılandırması
Önce AWS CLI kurulu ve yapılandırılmış olmalı. Eğer henüz yapmadıysanız:
# Linux için AWS CLI v2 kurulumu
curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
unzip awscliv2.zip
sudo ./aws/install
# Versiyon kontrolü
aws --version
# AWS kimlik bilgilerini yapılandır
aws configure
aws configure çalıştırdığınızda size dört şey soracak:
- AWS Access Key ID: IAM kullanıcınızın erişim anahtarı
- AWS Secret Access Key: Gizli anahtar
- Default region name: Hangi bölgede çalışacağınız, örneğin
eu-west-1 - Default output format:
jsonyazmanızı öneririm
Kimlik bilgilerini ~/.aws/credentials dosyasına yazıyor, yapılandırmayı ise ~/.aws/config dosyasına. Birden fazla AWS hesabıyla çalışıyorsanız profil kullanın:
# Farklı bir profil için yapılandırma
aws configure --profile production
# Profille komut çalıştırma
aws sqs list-queues --profile production
IAM Politikası Oluşturma
Güvenlik açısından SQS için ayrı bir IAM politikası ve kullanıcı oluşturmanız gerekiyor. Root hesabıyla ya da tam yetkili kullanıcıyla çalışmak ciddi güvenlik riski oluşturur.
Önce bir politika JSON dosyası hazırlayalım:
cat > sqs-policy.json << 'EOF'
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "SQSFullAccess",
"Effect": "Allow",
"Action": [
"sqs:CreateQueue",
"sqs:DeleteQueue",
"sqs:GetQueueAttributes",
"sqs:GetQueueUrl",
"sqs:ListQueues",
"sqs:SendMessage",
"sqs:ReceiveMessage",
"sqs:DeleteMessage",
"sqs:ChangeMessageVisibility",
"sqs:PurgeQueue"
],
"Resource": "arn:aws:sqs:eu-west-1:123456789012:*"
}
]
}
EOF
# Politikayı AWS'e yükle
aws iam create-policy
--policy-name SQSOperationsPolicy
--policy-document file://sqs-policy.json
Resource kısmındaki 123456789012 yerine kendi AWS hesap ID’nizi yazın. Bunu bulmak için aws sts get-caller-identity komutunu kullanabilirsiniz.
SQS Kuyruğu Oluşturma
Standard Kuyruk Oluşturma
En basit haliyle bir kuyruk oluşturmak tek satır:
# Basit standard kuyruk
aws sqs create-queue --queue-name siparis-kuyruğu
# Özelleştirilmiş kuyruk oluşturma
aws sqs create-queue
--queue-name siparis-isleme-kuyruğu
--attributes '{
"VisibilityTimeout": "60",
"MessageRetentionPeriod": "86400",
"ReceiveMessageWaitTimeSeconds": "20",
"MaximumMessageSize": "262144"
}'
Bu komuttaki önemli parametreler:
- VisibilityTimeout: Bir mesaj alındıktan sonra diğer tüketicilerden kaç saniye gizleneceği. Worker’ınızın mesajı işleme süresi + buffer olmalı. 60 saniye verdik.
- MessageRetentionPeriod: Mesajın kuyrukta kaç saniye tutulacağı. 86400 saniye = 1 gün. Maximum 14 gün (1209600 saniye).
- ReceiveMessageWaitTimeSeconds: Long polling için bekleme süresi. 20 saniye vermek boş polling’i azaltıp maliyeti düşürüyor. Kesinlikle 0 bırakmayın.
- MaximumMessageSize: Byte cinsinden maksimum mesaj boyutu. 262144 = 256 KB, SQS’in maksimum değeri.
FIFO Kuyruk Oluşturma
FIFO kuyruğu için ismin .fifo ile bitmesi zorunlu:
aws sqs create-queue
--queue-name kritik-islemler.fifo
--attributes '{
"FifoQueue": "true",
"ContentBasedDeduplication": "true",
"VisibilityTimeout": "30",
"MessageRetentionPeriod": "345600"
}'
ContentBasedDeduplication: Mesaj içeriğine göre otomatik tekrar kaldırma. Eğer aynı içerikli iki mesaj 5 dakika içinde gelirse ikincisi görmezden gelinir. Manuel deduplication ID vermek istemiyorsanız bunu true yapın.
Dead Letter Queue Kurulumu
Dead Letter Queue (DLQ), işlenemeyen mesajların gittiği yer. Bir mesaj belirli sayıda işlenmeye çalışılıp başarısız olursa otomatik olarak DLQ’ya taşınıyor. Bu olmadan başarısız mesajlar ya kaybolur ya da sonsuza kadar kuyruğu tıkar.
# Önce DLQ'yu oluştur
aws sqs create-queue
--queue-name siparis-dlq
--attributes '{
"MessageRetentionPeriod": "1209600"
}'
# DLQ'nun ARN'ını al
DLQ_ARN=$(aws sqs get-queue-attributes
--queue-url https://sqs.eu-west-1.amazonaws.com/123456789012/siparis-dlq
--attribute-names QueueArn
--query 'Attributes.QueueArn'
--output text)
echo "DLQ ARN: $DLQ_ARN"
# Ana kuyruğu DLQ ile birlikte oluştur
aws sqs create-queue
--queue-name siparis-isleme-kuyruğu
--attributes "{
"VisibilityTimeout": "60",
"MessageRetentionPeriod": "86400",
"ReceiveMessageWaitTimeSeconds": "20",
"RedrivePolicy": "{\"deadLetterTargetArn\":\"${DLQ_ARN}\",\"maxReceiveCount\":\"5\"}"
}"
maxReceiveCount: Bir mesaj kaç kez başarısız işlenirse DLQ’ya gönderilsin. 5 verdik, yani 5 kez denenip başarısız olan mesajlar DLQ’ya taşınıyor.
Mesaj Gönderme
Kuyruğu oluşturdunuz, şimdi mesaj gönderelim:
# Basit mesaj gönderme
aws sqs send-message
--queue-url https://sqs.eu-west-1.amazonaws.com/123456789012/siparis-isleme-kuyruğu
--message-body '{"siparis_id": "12345", "musteri": "[email protected]", "tutar": 299.99}'
# Mesaj özellikleri ile gönderme
aws sqs send-message
--queue-url https://sqs.eu-west-1.amazonaws.com/123456789012/siparis-isleme-kuyruğu
--message-body '{"siparis_id": "12346", "tutar": 150.00}'
--message-attributes '{
"siparis-tipi": {
"DataType": "String",
"StringValue": "express"
},
"oncelik": {
"DataType": "Number",
"StringValue": "1"
}
}'
--delay-seconds 10
--delay-seconds ile mesajın kuyruğa eklendikten kaç saniye sonra görünür olacağını belirtiyorsunuz. Ödeme onayı geldikten 10 saniye sonra kargo servisini tetiklemek istiyorsanız bu parametreyi kullanabilirsiniz.
Toplu mesaj göndermek için send-message-batch kullanın, 10 mesaja kadar tek seferde gönderebilirsiniz ve maliyet açısından çok daha verimli:
aws sqs send-message-batch
--queue-url https://sqs.eu-west-1.amazonaws.com/123456789012/siparis-isleme-kuyruğu
--entries '[
{"Id": "msg1", "MessageBody": "{"siparis_id": "101"}"},
{"Id": "msg2", "MessageBody": "{"siparis_id": "102"}"},
{"Id": "msg3", "MessageBody": "{"siparis_id": "103"}"}
]'
Mesaj Alma ve İşleme
# Mesaj alma
aws sqs receive-message
--queue-url https://sqs.eu-west-1.amazonaws.com/123456789012/siparis-isleme-kuyruğu
--max-number-of-messages 10
--wait-time-seconds 20
--message-attribute-names All
--attribute-names All
–max-number-of-messages: Tek seferde kaç mesaj alınacak, maksimum 10. –wait-time-seconds: Long polling süresi. Kuyruk boşsa bu kadar saniye bekler. Short polling (0) yerine daima long polling kullanın.
Mesajı aldıktan sonra işleyip silmeniz gerekiyor. Silmezseniz VisibilityTimeout süresinden sonra tekrar görünür hale gelir ve başka bir worker tarafından tekrar işlenir:
# Mesaj silme (ReceiptHandle değeri receive-message çıktısından alınır)
aws sqs delete-message
--queue-url https://sqs.eu-west-1.amazonaws.com/123456789012/siparis-isleme-kuyruğu
--receipt-handle "AQEBwJnKyrHigUMZj6reyNurx4JoNq69+G3GcGbNQrZC..."
Python ile Gerçekci Worker Uygulaması
CLI komutları işleri anlıyor ama gerçekte uygulamalar boto3 ile SQS’e bağlanıyor. İşte production’da kullanabileceğiniz bir worker örneği:
import boto3
import json
import logging
import time
from botocore.exceptions import ClientError
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
sqs = boto3.client('sqs', region_name='eu-west-1')
QUEUE_URL = 'https://sqs.eu-west-1.amazonaws.com/123456789012/siparis-isleme-kuyruğu'
def mesaji_isle(mesaj):
"""Mesajı işle ve True/False döndür"""
try:
govde = json.loads(mesaj['Body'])
siparis_id = govde.get('siparis_id')
logger.info(f"Sipariş işleniyor: {siparis_id}")
# Gerçek iş mantığınız buraya gelir
# fatura_olustur(siparis_id)
# email_gonder(govde['musteri'])
# stok_guncelle(govde['urunler'])
time.sleep(1) # İşlem simülasyonu
logger.info(f"Sipariş tamamlandı: {siparis_id}")
return True
except Exception as e:
logger.error(f"Mesaj işleme hatası: {e}")
return False
def worker_calistir():
logger.info("Worker başlatılıyor...")
while True:
try:
yanit = sqs.receive_message(
QueueUrl=QUEUE_URL,
MaxNumberOfMessages=10,
WaitTimeSeconds=20,
AttributeNames=['All'],
MessageAttributeNames=['All']
)
mesajlar = yanit.get('Messages', [])
if not mesajlar:
logger.debug("Kuyruk boş, bekleniyor...")
continue
for mesaj in mesajlar:
receipt_handle = mesaj['ReceiptHandle']
if mesaji_isle(mesaj):
# Başarılı işlem, mesajı sil
sqs.delete_message(
QueueUrl=QUEUE_URL,
ReceiptHandle=receipt_handle
)
logger.info("Mesaj silindi")
else:
# Başarısız, visibility timeout'u sıfırla
# Böylece başka worker hemen alabilir
sqs.change_message_visibility(
QueueUrl=QUEUE_URL,
ReceiptHandle=receipt_handle,
VisibilityTimeout=0
)
logger.warning("Mesaj işlenemedi, tekrar kuyruğa alındı")
except ClientError as e:
logger.error(f"SQS hatası: {e}")
time.sleep(5)
if __name__ == '__main__':
worker_calistir()
Bu worker’ı systemd servisi olarak çalıştırabilir ya da Docker container içinde Kubernetes’te deploy edebilirsiniz.
Kuyruk İzleme ve Yönetim
Kuyruğun durumunu kontrol etmek için:
# Kuyruk özelliklerini ve mesaj sayısını görüntüle
aws sqs get-queue-attributes
--queue-url https://sqs.eu-west-1.amazonaws.com/123456789012/siparis-isleme-kuyruğu
--attribute-names
ApproximateNumberOfMessages
ApproximateNumberOfMessagesNotVisible
ApproximateNumberOfMessagesDelayed
CreatedTimestamp
LastModifiedTimestamp
# Tüm kuyruklarınızı listeleyin
aws sqs list-queues --queue-name-prefix siparis
# Kuyruğu temizle (DİKKAT: Tüm mesajlar silinir, geri alınamaz!)
aws sqs purge-queue
--queue-url https://sqs.eu-west-1.amazonaws.com/123456789012/siparis-isleme-kuyruğu
ApproximateNumberOfMessages ile işlenmeyi bekleyen mesajları, ApproximateNumberOfMessagesNotVisible ile işlenmekte olan (visibility timeout içindeki) mesajları görürsünüz. Bu iki değer aniden büyümeye başlarsa worker’larınızda sorun var demektir.
CloudWatch alarmı kurarak kuyruk boyutu belirli bir eşiği geçtiğinde SNS üzerinden bildirim alabilirsiniz:
aws cloudwatch put-metric-alarm
--alarm-name "SiparisKuyrugu-Yuksek-Boyut"
--alarm-description "Siparis kuyruğu 1000 mesajı gecti"
--metric-name ApproximateNumberOfMessagesVisible
--namespace AWS/SQS
--statistic Maximum
--dimensions Name=QueueName,Value=siparis-isleme-kuyruğu
--period 300
--evaluation-periods 1
--threshold 1000
--comparison-operator GreaterThanThreshold
--alarm-actions arn:aws:sns:eu-west-1:123456789012:ops-alert
Güvenlik: Kuyruk Erişim Politikası
Varsayılan olarak sadece kuyruk sahibi mesaj gönderip alabilir. Başka bir AWS hesabının ya da servisin erişmesi gerekiyorsa kaynak tabanlı politika eklemeniz gerekiyor:
aws sqs set-queue-attributes
--queue-url https://sqs.eu-west-1.amazonaws.com/123456789012/siparis-isleme-kuyruğu
--attributes '{
"Policy": "{"Version":"2012-10-17","Statement":[{"Sid":"LambdaAccess","Effect":"Allow","Principal":{"Service":"lambda.amazonaws.com"},"Action":["sqs:SendMessage","sqs:ReceiveMessage"],"Resource":"arn:aws:sqs:eu-west-1:123456789012:siparis-isleme-kuyruğu"}]}"
}'
Hassas veri içeren mesajlar için sunucu tarafı şifreleme de açabilirsiniz. AWS managed key ile ücretsiz:
aws sqs set-queue-attributes
--queue-url https://sqs.eu-west-1.amazonaws.com/123456789012/siparis-isleme-kuyruğu
--attributes '{
"SqsManagedSseEnabled": "true"
}'
Kendi KMS anahtarınızı kullanmak isterseniz KmsMasterKeyId parametresiyle CMK ARN’ını verebilirsiniz.
Maliyet Optimizasyonu İpuçları
SQS ucuz bir servis ama yanlış kullanırsanız fatura şişebilir. Dikkat edilmesi gerekenler:
- Long polling kullanın:
ReceiveMessageWaitTimeSecondsdeğerini 20 yapın. Short polling her boş yanıt için ücretlendiriliyor, long polling çok daha az istek atıyor. - Batch işlemleri tercih edin: 10 ayrı mesaj yerine tek
send-message-batchisteği kullanın. 10 mesajı tek API çağrısıyla gönderebilirsiniz. - FIFO gereksizse Standard kullanın: FIFO kuyruğu Standard’dan daha pahalı. Sıra önemli değilse Standard tercih edin.
- Mesaj boyutunu optimize edin: Büyük payload yerine S3’e referans koyun. 256 KB üzeri zaten SQS’e sığmıyor, büyük veriyi S3’e at, SQS’e S3 obje URL’ini gönder.
- DLQ mesajlarını ihmal etmeyin: DLQ’da biriken mesajlar hem yer tutar hem de sorunların gözden kaçmasına neden olur. Düzenli kontrol edin.
Sonuç
AWS SQS, uygulama bileşenlerini birbirinden ayırmanın en kolay ve güvenilir yollarından biri. Bu yazıda Standard ve FIFO kuyruk oluşturmayı, Dead Letter Queue ile hata toleransı sağlamayı, mesaj gönderip almayı, Python ile gerçekçi bir worker yazmayı, izleme ve güvenlik ayarlarını ele aldık.
Kurulumu tamamladıktan sonra yapmanızı tavsiye ettiğim ilk şey DLQ’nuzu mutlaka kurmak ve CloudWatch alarmını aktif etmek. İkincisi worker uygulamanızın başarısız mesajlar için ne yapacağını netleştirmek. Üçüncüsü ise long polling’i açık tutmak.
SQS konusunda ilerlemek istiyorsanız bir sonraki adım olarak Lambda ile SQS entegrasyonunu incelemenizi öneririm. Lambda’yı SQS event source olarak tanımladığınızda worker yönetimiyle bile uğraşmıyorsunuz, mesaj geldikçe Lambda otomatik tetikleniyor. Mikroservis mimarisi için oldukça temiz bir çözüm.
