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: json yazmanı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: ReceiveMessageWaitTimeSeconds değ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-batch isteğ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.

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir