İçeriğe atla

2025-09-04

Olay Güdümlü Mimari Araçları: Kafka, SQS, EventBridge ve Cloud Alternatifleri Üzerine Kapsamlı Rehber

Olay güdümlü sistem araçları, mesaj teslimat kalıpları, DLQ stratejileri ve cloud provider eşlenikleri üzerine derinlemesine inceleme. AWS, Azure, GCP ve edge deployment'lar hakkında production deneyimleri.

Olay güdümlü sistemlerde doğru aracı seçmek hype’tan çok trade-off’ları anlamakla ilgili. Bu yazıda mesaj kalıplarından başlayıp AWS, Azure ve GCP eşleniklerine, DLQ stratejilerine ve edge deployment’a geçiyoruz.

Mesaj Kalıpları: Temel

Her pattern farklı araçlar ve trade-off’lar getirir:

1’e 1 (Kuyruk Kalıbı)

  • Mesaj tek consumer tarafından tüketilir (FIFO ile tam olarak bir kez)
  • Kullanım: Task işleme, iş dağıtımı, async job’lar
  • Araçlar: SQS, Azure Service Bus Queues, Cloud Tasks

1’e Çok (Topic/Fan-out Kalıbı)

  • Mesaj birden fazla subscriber’a iletilir; her biri kendi kopyasını alır
  • Kullanım: Event yayınlama, bildirimler, audit log
  • Araçlar: SNS, Azure Service Bus Topics, Cloud Pub/Sub

Çok’a Çok (Event Mesh)

  • Birden fazla producer/consumer arası karmaşık routing, filtreleme
  • Kullanım: Microservices iletişimi, domain event’leri
  • Araçlar: EventBridge, Azure Event Grid, Eventarc

Tam Araç Manzarası

Basit Kuyruk Servisleri

AWS SQS (Simple Queue Service)

Neyde öne çıkıyor: Çok basit kuyruk operasyonları, serverless entegrasyon, otomatik ölçekleme

Çalışan gerçek production config:

// Uygun error handling ve DLQ ile SQS
const params = {
  QueueUrl: 'https://sqs.us-east-1.amazonaws.com/123/my-queue',
  ReceiveMessageWaitTimeSeconds: 20,  // Long polling
  MaxNumberOfMessages: 10,
  VisibilityTimeout: 30,  // İşleme penceresi
  MessageAttributeNames: ['All']
};

// DLQ konfigürasyonu
const dlqParams = {
  QueueName: 'my-queue-dlq',
  Attributes: {
    MessageRetentionPeriod: '1209600',  // 14 gün
    RedrivePolicy: JSON.stringify({
      deadLetterTargetArn: dlqArn,
      maxReceiveCount: 3  // DLQ'ya gitmeden önce 3 kez dene
    })
  }
};

Teslimat garantileri:

  • Standard Queue: En az bir kez (olası duplikasyonlar)
  • FIFO Queue: Tam olarak bir kez işleme
  • Mesaj sıralaması: Sadece FIFO
  • Max mesaj boyutu: 1MB (Ağustos 2025’te 256KB’den yükseltildi)

Not: Mesaj boyutu limitindeki bu 4x artış, daha büyük veri alışverişi gerektiren AI, IoT ve karmaşık uygulama entegrasyon workload’ları için faydalıdır. AWS Lambda’nın event source mapping’i de yeni 1MB payload’ları destekleyecek şekilde güncellendi.

SQS ne zaman parlıyor:

  • Microservices’i decouple etme
  • Batch job işleme
  • Serverless mimariler (Lambda trigger’ları)
  • Basit task kuyrukları

Azure Service Bus Queues

Enterprise özellikleriyle SQS’in Azure eşleniği:

// Session'lar ve DLQ handling ile Service Bus
var client = new ServiceBusClient(connectionString);
var processor = client.CreateProcessor(queueName, new ServiceBusProcessorOptions
{
    MaxConcurrentCalls = 10,
    AutoCompleteMessages = false,
    MaxAutoLockRenewalDuration = TimeSpan.FromMinutes(5),
    SubQueue = SubQueue.DeadLetter  // DLQ'ya erişim
});

// Duplikasyon algılamalı mesaj
var message = new ServiceBusMessage(body)
{
    MessageId = Guid.NewGuid().ToString(),  // Deduplication için
    SessionId = sessionId,  // Sıralı işleme için
    TimeToLive = TimeSpan.FromMinutes(5)
};

SQS’ten temel farklar:

  • Sıralı işleme için built-in session’lar
  • Duplikasyon algılama (yapılandırılabilir pencere)
  • Zamanlanmış mesajlar
  • Mesaj boyutu: 256KB (standard), 100MB (premium)

Google Cloud Tasks

HTTP target entegrasyonlu GCP task kuyruğu:

import { CloudTasksClient } from '@google-cloud/tasks';

const client = new CloudTasksClient();
const parent = client.queuePath(project, location, queue);

const task = {
    httpRequest: {
        httpMethod: 'POST',
        url: 'https://example.com/process',
        headers: { 'Content-Type': 'application/json' },
        body: Buffer.from(JSON.stringify(payload))
    },
    scheduleTime: { seconds: Math.floor(timestamp / 1000) }
};

const response = await client.createTask({ parent, task });

Pub/Sub Sistemleri

AWS SNS (Simple Notification Service)

1’e çok mesaj dağıtımı:

// Akıllı routing için filter policy'li SNS
const publishParams = {
  TopicArn: 'arn:aws:sns:us-east-1:123:my-topic',
  Message: JSON.stringify(event),
  MessageAttributes: {
    eventType: { DataType: 'String', StringValue: 'ORDER_CREATED' },
    priority: { DataType: 'Number', StringValue: '1' }
  }
};

// Filter'lı subscription
const subscriptionPolicy = {
  eventType: ['ORDER_CREATED', 'ORDER_UPDATED'],
  priority: [{ numeric: ['>', 0] }]
};

SNS + SQS Pattern (Fanout):

Producer

SNS Topic

SQS Queue 1

SQS Queue 2

SQS Queue 3

Consumer 1

Consumer 2

Consumer 3

Teslimat garantileri:

  • En az bir kez teslimat
  • Mesaj sıralaması yok
  • Exponential backoff ile retry
  • Başarısız teslimatlar için DLQ desteği

Azure Service Bus Topics

SNS’ten daha sofistike:

// Birden fazla subscription ve filter'lı topic
var adminClient = new ServiceBusAdministrationClient(connectionString);

await adminClient.CreateSubscriptionAsync(
    new CreateSubscriptionOptions(topicName, subscriptionName),
    new CreateRuleOptions("OrderFilter",
        new SqlRuleFilter("EventType = 'OrderCreated' AND Priority > 5"))
);

Gelişmiş özellikler:

  • SQL benzeri filtre kuralları
  • Sıralama için mesaj session’ları
  • Duplikasyon algılama
  • Sebep takipli dead-lettering

Google Cloud Pub/Sub

Global mesaj dağıtımı:

import { PubSub } from '@google-cloud/pubsub';

const pubsub = new PubSub();
const topic = pubsub.topic(topicId);

// Ordering key ile yayınlama
const messageId = await topic.publishMessage({
    data: Buffer.from(data),
    orderingKey: 'user-123',
    attributes: {
        event_type: 'user_updated',
        version: '2'
    }
});

Event Routing Servisleri

AWS EventBridge

Kural tabanlı event routing:

const rule = {
  Name: 'OrderProcessingRule',
  EventPattern: JSON.stringify({
    source: ['order.service'],
    'detail-type': ['Order Created'],
    detail: {
      amount: [{ numeric: ['>', 100] }],
      country: ['US', 'UK', 'DE']
    }
  }),
  Targets: [{ Arn: lambdaArn, RetryPolicy: { MaximumRetryAttempts: 2 } }]
};

Azure Event Grid

Güçlü filtreleme ile Azure eşleniği: Subject ve advanced filter desteği. Blob storage, Cosmos DB ve custom event kaynakları.

Google Cloud Eventarc

GCP’nin birleşik eventing’i: Eventarc trigger’ları ile Cloud Run, GKE ve Cloud Functions entegrasyonu.

Stream Processing Platformları

Apache Kafka

Event streaming’in ağır siklet şampiyonu: Exactly-once semantik, yüksek throughput. Kafka Streams ile gerçek zamanlı işleme. DLQ pattern’leri producer ile orders-dlq topic’e gönderim.

Cloud Streaming Eşlenikleri

AWS Kinesis Data Streams

Enhanced fan-out ile düşük latency. Kinesis Data Analytics ile SQL tabanlı stream işleme.

Azure Event Hubs

Kafka protocol desteği. Capture to Data Lake ile uzun süreli depolama.

Google Cloud Dataflow

Pub/Sub okuma, windowing, BigQuery yazma ile stream pipeline’ları.

Dead Letter Queue (DLQ) Esasları

DLQ’lar production dayanıklılığı için kritiktir: başarısız mesajlar için güvenlik ağı sağlar, poison pill senaryolarını önler. RedrivePolicy ile maxReceiveCount kullanın. Detaylı rehber: Dead Letter Queue Production Strategies.

Edge ve Hybrid Deployment’lar

Edge Computing Değerlendirmeleri

Edge event sistemleri benzersiz kısıtlamalara sahip:

// Edge-optimize edilmiş event işleme
class EdgeEventProcessor {
  private localQueue: Queue[] = [];
  private cloudBuffer: Message[] = [];

  async processEvent(event: Event) {
    // Önce lokal işle
    const processed = await this.localProcess(event);

    // Cloud sync için batch'le
    if (this.shouldSyncToCloud(processed)) {
      this.cloudBuffer.push(processed);

      if (this.cloudBuffer.length >= 100 ||
          Date.now() - this.lastSync > 60000) {
        await this.syncToCloud();
      }
    }
  }

  private async syncToCloud() {
    try {
      // Sıkıştır ve batch gönder
      const compressed = this.compress(this.cloudBuffer);
      await this.cloudClient.sendBatch(compressed);
      this.cloudBuffer = [];
    } catch (error) {
      // Cloud ulaşılamazsa lokal sakla
      await this.localStorage.store(this.cloudBuffer);
    }
  }
}

Cloudflare Workers ile Kuyruklar

// Cloudflare Workers Queue Handler
export default {
  async queue(batch: MessageBatch, env: Env): Promise<void> {
    for (const message of batch.messages) {
      try {
        // Edge'de işle
        const result = await processMessage(message.body);

        // Durable Objects veya KV'de sakla
        await env.KV.put(
          `processed:${message.id}`,
          JSON.stringify(result),
          { expirationTtl: 3600 }
        );

        message.ack();
      } catch (error) {
        // Backoff ile retry
        message.retry({ delaySeconds: 30 });
      }
    }
  }
};

AWS IoT Core ile Edge Event’leri

Greengrass ile edge event işleme; lokal processing sonrası IoT Core topic’lere publish.

Cross-Cloud Eşlenikler

Servis Eşleme Tablosu

AWSAzureGCPKullanım Alanı
SQSService Bus QueuesCloud TasksBasit kuyruk
SNSService Bus TopicsCloud Pub/SubPub/Sub mesajlaşma
EventBridgeEvent GridEventarcEvent routing
KinesisEvent HubsPub/Sub + DataflowStream processing
Lambda + SQSFunctions + Service BusCloud Run + Pub/SubServerless event’ler
DynamoDB StreamsCosmos DB Change FeedFirestore TriggersDatabase event’leri
Step FunctionsLogic AppsWorkflowsEvent orchestration
MSK (Kafka)Event Hubs (Kafka mode)Confluent CloudKafka-uyumlu

Multi-Cloud Event Bridge Pattern

CloudEvent adapter interface ile AWS, Azure ve GCP arasında soyutlama. publishToAll ile çoklu cloud’a event gönderimi, partial failure handling.

Performance Karşılaştırma Matrisi

AraçThroughputLatencyMesaj BoyutuSıralamaTeslimat GarantisiDLQ Desteği
SQS Standard3K/sec batch10-100ms1MBHayırEn az bir kezEvet
SQS FIFO300/sec10-100ms1MBEvetTam olarak bir kezEvet
SNS100K/sec100-500ms256KBHayırEn az bir kezEvet
Kafka1M+/sec<10ms1MB defaultPartition başınaYapılandırılabilirManuel
RabbitMQ50K/sec1-5ms128MBOpsiyonelEn az bir kezEvet
EventBridge10K/sec500ms-2s256KBHayırEn az bir kezEvet
Kinesis1MB/sec/shard200ms1MBShard başınaEn az bir kezManuel
Azure Service Bus2K/sec10-50ms256KB/100MBEvetEn az bir kezEvet
Cloud Pub/Sub100MB/sec100ms10MBKey başınaEn az bir kezEvet

Karar Çerçevesi

Hızlı Karar Ağacı

Evet

Hayır

AWS

Azure

GCP

Evet

Yüksek

Orta

Event Sistemi Gerekli

Basit Kuyruk?

Cloud Native?

Streaming Gerekli?

SQS

Service Bus

Cloud Tasks

Hacim?

Kafka/MSK

Kinesis/EventHubs

Ne Zaman Ne Kullanılır

  • Basit Kuyruklar (SQS/Service Bus): Servisleri decouple etme, iş dağıtımı, serverless işleme
  • Pub/Sub (SNS/Topics): Event yayınlama, fan-out, birden fazla consumer, bildirimler
  • Event Router’lar (EventBridge/EventGrid): Karmaşık routing, multi-service orchestration, SaaS entegrasyonları
  • Streaming (Kafka/Kinesis): Real-time analitik, event sourcing, yüksek throughput, event replay

Yaygın Tuzaklar ve Çözümler

Tuzak 1: Mesaj Boyut Limitleri

// Çözüm: Claim check pattern
class LargeMessageHandler {
  async send(largePayload: any) {
    if (JSON.stringify(largePayload).length > 256000) {
      // S3'e sakla
      const s3Key = await this.uploadToS3(largePayload);

      // Referans gönder
      return this.queue.send({
        type: 'large_message',
        s3Key,
        size: largePayload.length
      });
    }

    return this.queue.send(largePayload);
  }
}

Tuzak 2: Zehirli Mesajlar

// Çözüm: Zehirli mesaj algılama
class PoisonMessageDetector {
  private messageAttempts = new Map<string, number>();

  async process(message: Message) {
    const attempts = this.messageAttempts.get(message.id) || 0;

    if (attempts >= 3) {
      // Zehirli mesaj olarak tanımlandı
      await this.quarantine(message);
      return;
    }

    try {
      await this.processMessage(message);
      this.messageAttempts.delete(message.id);
    } catch (error) {
      this.messageAttempts.set(message.id, attempts + 1);

      if (this.isPoisonPattern(error)) {
        await this.quarantine(message);
      } else {
        throw error; // Retry
      }
    }
  }
}

Tuzak 3: Sıralama Garantileri

// Çözüm: Partition key stratejisi
class OrderedEventProcessor {
  async publishOrdered(events: Event[]) {
    // Entity ID'ye göre sıralama için grupla
    const grouped = this.groupBy(events, e => e.entityId);

    for (const [entityId, entityEvents] of grouped) {
      // Timestamp'e göre sırala
      entityEvents.sort((a, b) => a.timestamp - b.timestamp);

      // Aynı partition key ile gönder
      for (const event of entityEvents) {
        await this.kafka.send({
          topic: 'events',
          key: entityId,  // Sıralamayı garanti eder
          value: event
        });
      }
    }
  }
}

Monitoring ve Gözlemlenebilirlik

Takip Edilecek Temel Metrikler

// Kapsamlı metrik toplama
class EventMetrics {
  private metrics = {
    messagesPublished: new Counter('messages_published_total'),
    messagesConsumed: new Counter('messages_consumed_total'),
    messagesFailed: new Counter('messages_failed_total'),
    processingDuration: new Histogram('message_processing_duration_seconds'),
    queueDepth: new Gauge('queue_depth'),
    consumerLag: new Gauge('consumer_lag'),
    dlqDepth: new Gauge('dlq_depth')
  };

  async recordProcessing(message: Message, processor: Function) {
    const timer = this.metrics.processingDuration.startTimer();

    try {
      const result = await processor(message);
      this.metrics.messagesConsumed.inc();
      return result;
    } catch (error) {
      this.metrics.messagesFailed.inc({
        error_type: error.constructor.name,
        queue: message.source
      });
      throw error;
    } finally {
      timer();
    }
  }
}

Sonuç

Anahtar noktalar: mesaj kalıpları araç seçimini belirler; teslimat garantileri mimariyi etkiler; DLQ stratejileri production’ı oyuncak sistemlerden ayırır; cloud eşlenikleri çoğu pattern için mevcut; edge gereksinimleri özel değerlendirme ister. Basit başla, ölç ve gerçek gereksinimlere göre evrimleş. Failure için tasarla; en iyi mimari güvenilirlik ve gözlemlenebilirliği korurken ihtiyaçlarla birlikte evrimleşebilendir.


İlgili Derinlemesine İncelemeler:

İlgili yazılar

Kafka mı, Event Bus mı? SNS/SQS/EventBridge'i Aşmanız Gerektiğini Söyleyen Sinyaller

Yönetilen bir event bus'tan Kafka'ya geçişi hak eden sinyaller ve rip-and-replace yapmadan taşımak için outbox tabanlı dört aşamalı geçiş planı.

kafkaevent-drivenaws+4
Dead Letter Queue Stratejileri: Dayanıklı Olay-Güdümlü Sistemler için Production-Ready Kalıplar

DLQ stratejileri, monitoring ve recovery kalıpları için kapsamlı rehber. Circuit breaker, exponential backoff, ML-tabanlı recovery ve kaçınılması gereken anti-pattern'lar hakkında gerçek production deneyimleri.

azurecircuit-breakerdead-letter-queue+6
WebAssembly 101: Üç Bahis, Tek Bytecode

Stack'ten bağımsız bir WebAssembly haritası (tarayıcıda performans, sunucuda WASI runtime, edge'de compute) üç farklı bahsi ayırarak hangi konuşmanın hangisinden bahsettiğini anlamanı sağlar.

webassemblywasmwasi+2
İzole Consumer Hesaplarına Event Fan-Out: Sıfır Dokunuşlu Producer, Domain Başına Sahiplik

Çok takımlı AWS organizasyonları için platform mühendisliği varsayılanı: tek event, birçok consumer, her biri kendi hesabında kendi SQS ve DLQ'suyla; fan-out event bus katmanında yaşar.

awseventbridgeevent-driven+5
Multi-Account AWS Mimarisi: Ölçeklenebilir Event-Driven Sistemler

Dayanıklı event-driven sistemler için multi-account AWS mimari pattern'lerini öğrenin. Hesap yapısı, EventBridge routing, servisler arası iletişim ve dağıtık sistemlerde operasyonel zorlukları keşfedin.

awseventbridgemulti-account+5