irdaweb Bilgi Teknolojileri
Telefon numaramız +90 541 209 02 05
E-posta adresimiz [email protected]
Konu 19 · Message Queues & Event

Message Queues ve event — asenkron iletişim, pub/sub ve teslimat garantileri.

İki servis birbirine doğrudan ve eşzamanlı bağlandığında, biri yavaşladığında ya da düştüğünde diğeri de onunla birlikte bekler. Mesaj kuyruğu, gönderen ile alanın arasına bir tampon koyar: gönderen mesajı bırakır ve işine devam eder, alan hazır olduğunda mesajı kendi hızında işler. Bu sayfada senkron ile asenkron iletişimin farkını, bir mesajın hangi rollerden geçtiğini, hangi teslimat garantileriyle taşındığını ve event-driven mimarinin bu işin neresinde durduğunu birlikte ve adım adım yan yana koyduk.

01 — Temeller

Mesaj kuyruğu nedir, senkron ve asenkron iletişim nasıl ayrışır?

Senkron iletişimde gönderen, alandan yanıt gelene kadar bekler; iki servisin kaderi birbirine bağlanır. Asenkron iletişimde gönderen mesajı bir aracıya bırakıp işine devam eder, alan onu daha sonra işler. Mesaj kuyruğu (message queue) tam da bu aracıdır: gönderen ile alanı zaman ve hız açısından birbirinden ayırır (decoupling). Böylece alan yavaşladığında ya da geçici olarak düştüğünde mesajlar kaybolmaz, kuyrukta birikir ve sıra gelince işlenir.

Senkron vs asenkron akış farkı
# senkron — gönderen yanıtı bekler
servis A → servis B           # B yavaşsa A da bekler
        ← yanıt

# asenkron — araya kuyruk girer
servis A → [ queue ]          # A bırakır, devam eder
           [ queue ] → servis B  # B hazır olunca işler
DecouplingBağımsızlaştırma

Gönderen ile alan birbirini tanımak ya da aynı anda ayakta olmak zorunda değildir. Biri değişse de diğeri etkilenmez; sistem parçaları gevşek bağlı kalır.

BufferTampon & dayanıklılık

Ani yük artışında mesajlar kuyrukta birikir, alan kendi hızında tüketir. Alan kısa süreli düşse bile mesajlar kaybolmaz.

AsyncYanıt beklemeden

Kullanıcıyı bekletmeden, e-posta gönderimi veya rapor üretimi gibi uzun işler arka plana atılır. Yanıt hızlanır, ağır iş sonra yapılır.

02 — Bileşenler

Producer, broker ve consumer: bir mesajın yolculuğu

Asenkron mesajlaşma üç rol etrafında döner. Producer mesajı üreten ve gönderen taraftır; broker mesajı saklayan ve yönlendiren aracı sistemdir (RabbitMQ, Kafka gibi); consumer ise mesajı alıp işleyen taraftır. Broker'ın içinde mesajlar ya bir queue'da (sıralı, tek tüketiciye giden) ya da bir topic'te (yayınlanan, çok aboneye dağıtılan) tutulur. Bu rollerin net ayrılması, sistemin gevşek bağlı kalmasının temelidir.

Akış producer → broker → consumer
Producer  mesajı üretir ve publish eder
   │
   ▼
Broker    mesajı saklar ve yönlendirir
   │        # queue ya da topicConsumer  mesajı çeker, işler, ack'ler

# ack gelmezse broker mesajı yeniden teslim eder

Producer — üretici

Mesajı oluşturup broker'a gönderir. Alanı tanımaz; yalnızca hangi queue ya da topic'e yazacağını bilir. Mesaj gittikten sonra işine devam eder.

Broker — aracı

Mesajı kabul eder, dayanıklı biçimde saklar ve doğru tüketiciye yönlendirir. Sıralama, dağıtım ve teslimat garantilerinin uygulandığı yer burasıdır.

Consumer — tüketici

Mesajı broker'dan çeker, işler ve başarıyla bitince ack gönderir. Birden çok consumer aynı kuyruğu paylaşarak yükü bölüşebilir.

03 — Mesajlaşma desenleri

Queue, pub/sub ve fan-out

Bir mesajın kaç tüketiciye ve nasıl ulaşacağı bir desen seçimidir. Point-to-point queue'da her mesaj tek bir tüketici tarafından işlenir; iş bölüşülür. Publish/subscribe'da (pub/sub) bir topic'e yayınlanan mesaj tüm abonelere kopyalanır; aynı olay birçok yerde tepki üretir. Fan-out, tek mesajın birçok kuyruğa dağıtıldığı bu yayılmanın adıdır. Doğru desen, "bu mesajı biri mi yapsın, herkes mi duysun" sorusunun yanıtına bağlıdır.

Desen Kim alır
Point-to-point Tek tüketici
Pub/Sub Tüm aboneler
Fan-out Birçok kuyruk
Consumer group Grup içinde tek üye
Queue

Point-to-point

Mesaj tek bir tüketiciye gider; birden çok tüketici varsa iş aralarında bölüşülür. Aynı işi iki kez yaptırmamak için idealdir.

Pub/Sub

Publish / subscribe

Bir olay birçok bağımsız aboneyi tetikler. "Sipariş verildi" olayına hem fatura hem stok hem bildirim servisi ayrı ayrı tepki verir.

Consumer group

Ölçeklenir tüketim

Kafka'da bir grup içindeki tüketiciler partition'ları paylaşır; hem yük dağılır hem partition içinde sıralama korunur.

04 — Teslimat garantileri

At-least-once, at-most-once ve ack/idempotency

Bir mesajın "kaç kez teslim edileceği" sistemin en kritik tasarım kararıdır. At-most-once en fazla bir kez teslim eder; kayıp olabilir ama tekrar olmaz. At-least-once en az bir kez teslim eder; kayıp olmaz ama aynı mesaj birden çok gelebilir. Exactly-once arada idealdir ama gerçekte yalnızca idempotent tüketici ile yaklaşılır. Anahtar mekanizma ack'tir: tüketici işi bitirince onay gönderir, gelmeyen mesaj yeniden teslim edilir.

Ack akışı at-least-once
broker → mesaj teslim eder
consumer  işi yapar
        → ack        # başarı: broker mesajı siler

broker → mesaj teslim eder
consumer  çöker, ack yok   # broker yeniden teslim eder
        → mesaj 2. kez gelir   # bu yüzden idempotency gerekir
At-most-once
Mesaj en fazla bir kez işlenir. Hızlıdır ve tekrar üretmez ama hata anında kaybolabilir. Kaybı tolere edilen metrik/telemetri gibi verilerde uygundur.
At-least-once
Mesaj asla kaybolmaz ama tekrar gelebilir. En yaygın varsayılandır; tüketicinin tekrarları zararsız kılması (idempotency) beklenir.
Exactly-once
Her mesaj tam bir kez işlenir. Uçtan uca tam garanti pahalı ve sınırlıdır; pratikte at-least-once + idempotent tüketici ile aynı sonuca varılır.
Idempotency
Aynı mesajı iki kez işlemenin tek kez işlemekle aynı sonucu vermesi. Mesaj kimliğini (message id) kaydedip tekrarı atlamak en yaygın yöntemdir.
05 — Event-driven mimari

Event ve command: olaya tepki veren sistemler

Event-driven mimaride servisler birbirini doğrudan çağırmaz; olan biteni bildiren olaylar (event) yayınlar ve ilgilenen servisler bunlara tepki verir. Bir event "olmuş bir şeyi" anlatır (OrderPlaced); bir command ise "yapılması istenen bir şeyi" söyler (PlaceOrder). Bu fark koordinasyon biçimini belirler: orchestration'da merkezî bir akış yönetir, choreography'de her servis kendi tepkisini olaylardan çıkarır.

Event tek olay, çok tepki
OrderPlaced  # olmuş bir şey yayınlanır
   ├─→ Fatura servisi     fatura oluştur
   ├─→ Stok servisi       stok düş
   └─→ Bildirim servisi   e-posta gönder

# producer aboneleri tanımaz; yenisi eklenince
# mevcut kod hiç değişmeden tepki verir.

Event vs command

Event olmuş bir gerçeği bildirir ve birçok aboneye açıktır; command belirli bir alıcıya "şunu yap" der. Event geçmiş zaman, command emir kipidir.

Choreography vs orchestration

Choreography'de her servis olaylara bakıp kendi adımını atar; orchestration'da merkezî bir koordinatör akışı yönetir. İlki gevşek bağlı, ikincisi izlenebilir kalır.

Event sourcing

Son durumu değil, ona götüren tüm olayları saklamak. Durum, olayların yeniden oynatılmasıyla üretilir; tam denetim izi ve geçmişe dönük analiz sağlar.

06 — Araçlar & senaryolar

Hangi araç nerede: broker, log ve yönetilen kuyruk

Araçlar iki temel yaklaşım etrafında toplanır. RabbitMQ gibi geleneksel broker'lar mesajı tüketildikten sonra siler ve zengin yönlendirme sunar; Kafka gibi sistemler ise mesajları kalıcı bir log olarak tutar, tüketiciler aynı veriyi tekrar tekrar okuyabilir. Bunların yanında SQS gibi yönetilen bulut kuyrukları ve Redis Streams gibi hafif çözümler vardır. Doğru seçim, yönlendirme ihtiyacınıza, kalıcılık beklentinize ve işletme yükünüze bağlıdır.

RabbitMQ

Klasik broker

Zengin yönlendirme (exchange, routing key) ve esnek teslimat. Mesaj tüketilince düşer; iş kuyruğu ve karmaşık dağıtım senaryolarında güçlüdür.

Kafka

Dağıtık log

Mesajları partition'lı, kalıcı bir log olarak tutar. Yüksek hacimli olay akışı, event sourcing ve birden çok tüketicinin aynı veriyi okuduğu durumlar için biçilmiş kaftandır.

Amazon SQS

Yönetilen kuyruk

Sunucu yönetmeden ölçeklenen bulut kuyruğu. Standart (at-least-once) ve FIFO seçenekleriyle, işletme yükünü en aza indiren pratik bir başlangıçtır.

Redis Streams

Hafif akış

Zaten Redis kullanıyorsanız, consumer group destekli hafif bir akış yapısı. Düşük gecikme ve sade kurulum ister, devasa hacim hedeflemez. Ayrıntı için Önbellekleme & Redis başlığına bakabilirsiniz.

Sidekiq

Arka plan işleri

Redis üzerine kurulu, uygulama içi arka plan iş kuyruğu. E-posta, rapor ve görüntü işleme gibi gecikmeli görevleri ana isteğin dışına taşır.

NATS

Düşük gecikme

Sade ve çok hızlı bir mesajlaşma sistemi; JetStream ile kalıcılık ekler. Servisler arası hafif, gecikmeye duyarlı iletişimde tercih edilir.

07 — Tuzaklar

Duplicate, ordering, dead letter ve backpressure

Asenkron mesajlaşma esneklik kazandırırken yeni başarısızlık biçimleri de getirir. Aynı mesaj birden çok kez gelebilir (duplicate); sıra garanti edilmeyebilir (ordering); işlenemeyen mesajlar sistemi tıkayabilir (poison message); tüketici üreticiye yetişemeyince kuyruk şişer (backpressure). Bunların her birinin bilinen bir savunması vardır ve dead letter queue, çoğunun ortak emniyet supabıdır.

Duplicate

Tekrarlı mesaj

At-least-once teslimatta aynı mesaj birden çok gelebilir. Tüketiciyi idempotent yapmak ve işlenen mesaj kimliklerini saklamak bunu zararsız kılar.

Ordering

Sıralama

Çoğu sistem global sıra garanti etmez; paralel tüketicilerde mesajlar karışabilir. Sıra önemliyse aynı anahtar aynı partition'a yönlendirilir.

Dead letter

Dead letter queue

Belirli denemeden sonra işlenemeyen mesaj ayrı bir kuyruğa (DLQ) taşınır. Ana akış tıkanmaz, sorunlu mesaj sonra incelenir.

Poison message

Zehirli mesaj

Hep hata veren bir mesaj sonsuz döngüde yeniden teslim edilir ve tüketiciyi kilitler. Deneme sayısını sınırlayıp DLQ'ya atmak çözer.

Backpressure

Geri baskı

Tüketici üreticinin hızına yetişemeyince kuyruk şişer ve bellek dolar. Tüketiciyi ölçeklemek, hız sınırlamak ve kuyruk derinliğini izlemek gerekir.

Exactly-once

Tam-bir-kez yanılgısı

Uçtan uca "tam bir kez" çoğu zaman bir efsanedir. Gerçekçi hedef at-least-once teslimat ile idempotent tüketicidir; bu pratikte aynı sonucu verir.

Kuyruk, hatayı yok etmez; erteler. Asenkron sistemde bir mesaj sessizce başarısız olabilir ve kimse fark etmeyebilir. Dead letter kuyruğunu, kuyruk derinliğini ve tüketici gecikmesini ilk günden izleyin; aksi halde sorunlar sessizce birikir.
08 — Sık karıştırılanlar

Sık karıştırılan mesajlaşma kavramları

Queue vs. Topic

Queue point-to-point çalışır: her mesaj tek bir tüketici tarafından işlenir, iş bölüşülür. Topic pub/sub çalışır: yayınlanan mesaj tüm abonelere kopyalanır. Soru basittir: bu mesajı biri mi yapsın, yoksa herkes mi duysun.

Message vs. Event

Message taşınan herhangi bir veri paketinin genel adıdır. Event ise olmuş bir şeyi bildiren özel bir mesaj türüdür ve genellikle yayınlanır. Her event bir message'dır ama her message bir event değildir; bir command de bir message'dır.

Kafka vs. RabbitMQ

Kafka mesajları kalıcı bir log olarak tutar; tüketiciler aynı veriyi tekrar okuyabilir, yüksek hacme uygundur. RabbitMQ klasik bir broker'dır; mesaj tüketilince düşer, zengin yönlendirme sunar. Olay akışı için Kafka, esnek iş kuyruğu için RabbitMQ öne çıkar.

At-least-once vs. Exactly-once

At-least-once mesajı kaybetmez ama tekrar teslim edebilir. Exactly-once her mesajı tam bir kez işler ama uçtan uca garantisi pahalı ve sınırlıdır. Pratikte at-least-once + idempotent tüketici, exactly-once'ın güvenilir karşılığıdır.

Choreography vs. Orchestration

Choreography'de servisler olaylara bakıp kendi adımını bağımsızca atar; gevşek bağlıdır ama akışı izlemek zorlaşır. Orchestration'da merkezî bir koordinatör adımları sırayla yönetir; izlenebilir ama merkeze bağımlıdır.

Birinci el kaynaklar

RabbitMQ, Kafka ve Amazon SQS'in resmi dokümantasyonu, olay biçimini standartlaştıran CloudEvents ve Redis Streams gibi tarafsız teknik referanslar.

Sıradaki adım

Asenkron mimarinizi birlikte tasarlayalım.

Doğru kurulmuş bir mesaj kuyruğu, sistemin parçalarını birbirinden ayırır ve yükü dengeler; yanlış kurulmuş bir kuyruk ise sessiz kayıplar ve takılmalar üretir. Nereye kuyruk koyacağınıza, hangi teslimat garantisini seçeceğinize ve olayları nasıl kurgulayacağınıza birlikte bakalım.