Saga Türleri: Choreography mi, Orchestration mı?
Servisler kendi kendine karar mı versin, yoksa tek bir otorite mi yönetsin? Dağıtık transaction’larda en doğru ritmi birlikte keşfedelim!
İlk makalede saga deseninin ne olduğunu konuştuk. Dağıtık transaction yönetiminin klasik yollarla çözülemediği mikroservis dünyasında, saga’nın adım adım ilerleyen, telafi edilebilir bir işlem modeli sunduğunu gördük.
Ama bu sadece başlangıçtı.
İlk makaleyi henüz okumadıysan öncelikle onu okumanı öneririm 👇
Şimdi, bu desenin nasıl hayata geçirileceğini konuşalım. Çünkü saga deseni deyince aslında iki farklı yaklaşım var: Choreography ve Orchestration.
İkisi de sistemleri koordine etmeyi amaçlıyor, ama yöntemleri oldukça farklı.
Ve evet, ikisinin de doğru kullanıldığı yerler, avantajları, hatta baş ağrıttığı senaryolar var.
Bu yazıda, bu iki yaklaşımı örneklerle detaylıca inceleyecek, hangi durumlarda hangisinin tercih edilmesi gerektiğine birlikte karar vermeye çalışacağız.
🩰 1. Choreography: Otonom Servislerin Dansı
Choreography, mikroservisler arasında sıkı bir orkestra yerine, serbest ama uyumlu bir akış gibidir. Günümüz dünyasında da en çok tercih edilen yöntemdir.
Her servis kendi rolünü bilir, ne zaman devreye gireceğini bir event’e göre tayin eder. Koordinasyonu merkezi bir yapı değildir, yayımlanan event’ler bu koordinasyonu sağlar.
Bu ne anlama geliyor?
Her servis:
İlgi duyduğu event’leri dinler,
O event geldiğinde kendi işini yapar,
Gerekirse yeni bir event yayınlar ve akışı devam ettirir.
💡 Örnek: Borsa Hisse Satış Süreci
Bir müşteri hisse satış talebinde bulunuyor:
Müşteri hisse satış talebi oluşturur ve Order domain’i → OrderCreated event’i yayınlanır.
Hesap hareketleri ve ücret servisleri, bu event’i alır, işlemlerini yapar ve tamamlandığını bildiren event’ler yayınlar. FeeCharged ve StockReserved.
Market servisi ise, hem ücretin tahsil edildiğini hem de stokun rezerve edildiğini gösteren event’leri bekler. İki event de geldikten sonra siparişi borsaya iletir ve işlem tamamlandığında “OrderPlaced” event’ini yayınlar.
Son olarakta OrderPlaced event’ini dinleten Order domain’i müşteriyi bilgilendirecek aksiyonları tetikler.
Her servis bağımsız çalışır. “Sıradaki adım nedir?” sorusunun cevabı, event’lerin üzerinde taşınır. Koordinasyonu merkezi bir otorite değil, akıştaki veriler sağlar.
Peki ya hata durumunda ne olacak?
Akışın herhangi bir durumunda bir hata meydana geldiğinde Choreography Saga’da her bir servis kendini initial state’e geri döndürebilmelidir. Bu nasıl olacak sorusunun cevabı ise tabii ki yine event’ler. Her bir task fail ettiğinde bun un bir de onarıcı aksiyonunun olması lazım.
C1 - Müşterinin yarattığı sipariş iptal edilmelidir.
C2- Rezerve edilen stok serbest bırakılması ve stok pozisyonu düzeltilmelidir.
C3 - Müşteriye ücret iadesi yapılması için gerekli süreç tetiklenmelidir.
C4 - Borsaya iletilen sipariş iptal edilmelidir.
C5 - Siparişin statüsü geri alınmalıdır.
✅ Avantajları
Loose coupling: Servisler birbirinden habersiz çalışabilir. Bu da değişimlere karşı sistemi daha dayanıklı kılar.
Yeni servis eklemek kolaydır: Sadece ilgili event’i dinlemesi yeterlidir.
Gerçek anlamda dağıtık yapı: Her şeyin merkezde toplanmadığı, ölçeklenebilir bir model sunar.
⚠️ Zorlukları
İzlenebilirlik zor: Bir siparişin tüm adımlarını izlemek, event loglarına bakmayı gerektirir. Karmaşık sistemlerde güçlü bir monitoring sistem gerektirir.
Gizli koordinasyon: Sistemin nasıl işlediğini anlamak için iyi dokümantasyon şart.
Versiyonlama ve uyum: Event şemalarında yapılacak değişiklikler zincirleme etkiler yaratabilir.
Dependency karmaşası: Örneğin order service hem market service’in dinleyeceği event’i yayımlar hem de market service’den yayımlanan event’i dinler. Buna cyclic dependency deniyor. Bu servislerin release zamanında birbirine olan bağımlılığını arttırıyor.
🎼 2. Orchestration: Tek Elden Yönetilen Süreçler
Orchestration, adından da anlaşılacağı gibi bir orkestra şefinin olduğu modeldir. Burada her servis kendi kafasına göre hareket etmez; bir merkezi koordinatör (orchestrator), süreci adım adım yönetir.
İletişimdeki servislerden bir tanesi orkestra şefi olarak belirlenir. Ve servislerin tüm akış boyunca iletişimi ve çıktılarını izlemekten sorumludur.
Bu yaklaşımda:
Tüm adımların sırasını ve geçişini bir servis belirler,
Diğer servisler sadece emir alır ve yanıt verir.
💡 Teknik Örnek: Sipariş Koordinatörü
Yine borsa sistemlerinde hisse satış örneğimize dönelim, ama bu sefer her şey bir sipariş koordinatörü tarafından yönetiliyor. Burada sipariş servisini bir state machine gibi düşünebiliriz.
Müşteri satış emri oluşturur ve sipariş oluşur → Orchestrator devreye girer.
Hesap Hareketleri ve Ücret Servislerine sipariş bilgilerini iletir ve işlemlerini yapmalarını söyler → her iki serviste de işlem başarılıysa devam eder.
Ardından Market Servisi’ne siparişin hazır olduğu bilgisini verir.
Eğer işlem başarılı ise market servisi Order Placed event’ini yayınlar.
Tüm sürecin kontrolü orchestrator’dadır. Hangi adımda ne yapılacağı, hangi adımın başarısız olması durumunda neye geçileceği merkezi olarak yazılmıştır. Bir saga log tutarak, işlem akışının bir muhasebesini saklar.
Tıpkı Choreography saga’da olduğu için bu Orchestration saga’da da her şey yolunda gitmeyebilir. Bu durumda da, order servis bir orkestra şefi görevini sürdürür ve hangi servisin ne yapması gerektiğini onlara gönderdiği event’ler ile söyler.
✅ Avantajları
Kontrol merkezi bir yerde: İş akışı nettir, sistemin nasıl çalıştığını tek yerden anlamak kolaydır.
Debug ve izleme kolaydır: Hangi adımda ne olduğuna dair görünürlük yüksektir.
Koordinasyon basit: Karmaşık iş akışlarını tanımlamak için idealdir.
⚠️ Zorlukları
Tekil bağımlılık: Orchestrator çökse sistem kilitlenebilir.
Yeniden kullanılabilirlik az: Her şey bir senaryoya özel yazılmıştır.
Sıkı bağlılık riski: Koordinatör, tüm servislerin detaylarını bilmek zorunda kalabilir.
Günümüzde Orchestration modeli Choreography modeline göre daha az tercih ediliyor. Bunun nedeni de mikroservislerin her birinin kendi yapacağı işe dair akıl sahibi olması düşüncesidir. Ama çok karmaşık ve izlenebilirliğin önemli olduğu sistemlerde Orchestration model de tercih edilebiliyor.
🎯 3.3 Birbirine Dolanmış Saga’lar (Interwoven Sagas)
Şimdiye kadar saga desenini hep izole, tekil işlemler gibi düşündük. Ama gerçek dünyada işler nadiren bu kadar temiz ilerler. Çünkü saga’lar ACID transaction’lar gibi izole değildir. Her adımın sonucu anında sistemde görünür hale gelir ve bu durum, aynı varlığın (örneğin bir siparişin) birden fazla eşzamanlı saga tarafından işlenmesine yol açabilir.
İşte burada işler karışır. Çünkü sistem, ara durumlarla (intermediate state) başa çıkmak zorunda kalır. Yani bir işlem tamamlanmadan, başka bir işlem onunla çakışabilir.
💡 Basit bir örnek: Müşteri yanlışlıkla bir satış emri verdi ve hemen iptal etmek istiyor. Ama sipariş henüz borsaya iletilmemiş. Yani saga hala devam ediyor. Bu durumda, iptal işlemi yeni bir saga başlatır ve sistem, henüz tamamlanmamış olan ilk saga’yı kesintiye uğratmak zorunda kalabilir.
Bu tür çakışmaları yönetmek için 3 yaygın strateji vardır:
⛔ Short-Circuiting (Kısa Devre):
Yeni bir saga başlatmayı engelleyebilirsin. Yani iptal işlemi, ancak ilk işlem tamamlandıktan sonra başlatılabilir. Uygulaması kolay ama kullanıcı deneyimi açısından pek ideal değil. Çünkü müşteri “siparişin ilerlemesini izleyip sonra iptal edebilirsin” gibi bir cevap alır.
🔐 Locking (Kilitleme):
Saga’ların aynı varlığı aynı anda değiştirmesini önlemek için kilit kullanabilirsin. Örneğin, bir hisse satış siparişi için stok rezerve edildiğinde, bu varlık kilitlenir. Başka bir işlem (örneğin iptal) bu kilidi beklemek zorunda kalır. Bu yaklaşım, klasik concurrency control tekniklerine benzer ama dikkatli olmazsan deadlock (kilitlenme) gibi ciddi sorunlara yol açabilir. Dolayısıyla timeout ve deadlock detection gibi önlemlerle desteklenmesi gerekir.
🔁 Interruption (Kesinti):
Belki de en dinamik yöntem bu. İşlem devam ederken gelen yeni talep (örneğin iptal), ilk işlemi “başarısız” duruma çekebilir. Market servisinden siparişi borsaya iletme mesajı geldiğinde, sistem siparişin en güncel statüsünü kontrol eder. Eğer statü “failed” ise, bu sipariş ilerlemez. Bu yaklaşım, deadlock riskini azaltır ama iş mantığını ciddi biçimde karmaşıklaştırır. Servisler birbirlerinin state’lerini anlamak ve kontrol etmek zorundadır.
Kapanış: Saga’yla Dağıtık Dünyayı Yönetmek
Bu iki makalede saga deseninin temelini, Choreography ve Orchestration yaklaşımlarını, hatta iç içe geçmiş (Interwoven) saga senaryolarını inceledik. Artık şunu biliyoruz:
Choreography, servisleri bağımsız tutar, event’lerle esnek bir akış sunar.
Orchestration, tüm süreci merkezi bir şef (orchestrator) yönetir, izlenebilirliği ve kontrolü kolaylaştırır.
Interwoven saga’lar, eşzamanlı işlemlerle ortaya çıkan ara durumlar için stratejiler (short-circuit, locking, interruption) gerektirir.
❓ Ne zaman hangisini kullanmalı?
Sistemin kalbinde tam ölçeklenebilirlik ve sürekli değişim varsa, Choreography ön planda.
Net iş akışları, kolay hata yönetimi ve güçlü izlenebilirlik şartsa, Orchestration daha doğru.
Karmaşık iptal, çakışma senaryoları varsa, Interwoven saga stratejilerini tasarlamak kaçınılmaz.
🔧 Uygulamada hatırlaman gerekenler:
Her iki modeli de tek bir “doğru” olarak görmek yerine, ihtiyacına ve ekibine göre hibrit kullanmaktan çekinme.
Monitoring, loglama ve dokümantasyon olmazsa olmaz. Event log’ları ve saga log’u, hata ayıklamada hayat kurtarır.
Ekip içi eğitim ve paylaşım, herkesin iş akışını anlaması için kritik.
Faydalı olacağını umduğum bu makalenin sonuna geldik!