Dağıtık sistemde Saga Pattern ile eventual consistency'yi nasıl tasarlarım?
Soru
Mikroservis mimarimizde sipariş akışı şöyle: Sipariş Servisi ödemeyi alır, Stok Servisi stok düşer, Kargo Servisi gönderi oluşturur. Kargo hata verdiğinde ödemenin iadesi ve stokların geri artırılması gerekiyor. 2PC performans sorunu çıkardığı için Saga Pattern kullanmak istiyoruz. Orchestrator tabanlı Saga'yı kuyruk mekanizmaları üzerinden nasıl tasarlarım?
Cevap
Kısa cevap: 2PC’den kaçınmanız doğru — o kilitlenir ve ölçeklenmez. Saga, tek bir atomik işlemi, her birinin bir telafi aksiyonu olduğu yerel işlemler dizisine çevirir. Sizin akışınız için orchestrator tabanlı Saga doğru tercih.
Kısa cevap
Asıl mesele şu: artık her şeyi tek transaction içinde geri alamazsınız. Bunun yerine, “bir adım bozulursa, daha önce yapılan adımları telafi et” disiplinini kurmanız lazım. Adımların taşındığı kuyruğun operasyonel tarafını Laravel queue ve Supervisor yazısında anlatmıştım.
Neden
-
Telafi, rollback değildir. İade gerçek bir işlemdir; “ileri yönde dengeleyici” bir adımdır. Bunu kabul etmek saga’nın tüm tasarımını belirler.
-
Kuyrukta retry garantidir. Aynı “stok düş” komutu iki kez gelebilir; idempotency olmadan saga ikinci denemede çift iade/çift stok üretir. Aynı disiplinin webhook tarafındaki hâlini mükerrer bildirim ve idempotency kaydında ele almıştım.
-
“İşi yap” ile “olayı yayınla” ayrı kalırsa saga ortada kalır. İş commit olur ama olay yayınlanmazsa akış hiç devam etmez.
Ne yapmalı
-
Merkezi koordinatör adımları kuyruktan sürsün. Orchestrator (Sipariş Servisi) komutları kuyruğa basar: ödemeyi rezerve et → stok düş → gönderi oluştur. Her servis işini bitirince sonucu geri bildirir. Akış tek bir yerde, açık ve okunabilir.
-
Hata olunca telafileri ters sırayla çalıştırın. Kargo adımı patlarsa orchestrator geriye doğru gider: stoğu geri artır, ödemeyi iade et.
-
Her adımı idempotent yapın. Her komuta deterministik bir
saga_id+step_idkoyun, işlenmişse tekrar işlemeyin. -
Outbox pattern ile atomikliği koruyun. İşi ve olayı aynı DB’deki
outboxtablosuna tek transaction’da yazın, ayrı bir relay kuyruğa taşısın. -
Saga durumunu kalıcı tutun. Hangi adımdasınız, hangileri tamamlandı — bir tabloda saklayın ki koordinatör çökse bile kaldığı yerden devam etsin.
Sonuç: Orchestration’ı choreography’ye tercih edin; akış açık ve telafi sıralaması net. Eventual consistency’yi kabul edin: stok birkaç saniye tutarsız görünebilir, sonra mutabık olur. Mimari kararı sade.dev’de derinleştiriyorum.
İlgili Yazılar
Yorumlar
Yorum yapmak için GitHub hesabınızla giriş yapmanız yeterli. Yorumlar GitHub Discussions üzerinde saklanır.