Outbox patterni kullanarak
Domain Eventleri nasıl
pushlayacağımızı öğreneceğiz. Outbox Pattern transactionumuzun
Atomik bir şekilde tamamlanmasını garanti etmek istediğimiz senaryolarda faydalıdır.
Problem
Event Driven Arthitecture, Loose Coupling servisler geliştirmek için kullandığımız yöntemlerden birisidir. Sistemde yapılan değişikliklerin events şeklinde ortak bir platforma, bir Message Brokera , yayımlanıplanıp oradanda farklı consumerler tarafından handle edilmesi üzerine kuruludur.
örn. X servisindeki bir işlem, Y servisini çağıracağına (http request), yaptığı işlemi message brokera yayımladıktan sonra, bu evente abone olan Y servisi, eventi yakalayıp handle ediyor. Bu sayede bu iki servisin bir birine olan bağımlılığını ortadan kaldırmış oluyoruz.
Yukarıdaki senaryoda X servisi kendi işlerini tamamlayıp daha sonra Y nin kendi işlerini yapması için gerekli olan eventi, message brokera yollayamazsa(message broker servisi ayakta olmayabilir) burada sorun ortaya çıkıyor. Veri bütünlüğü sağlanamamış oluyor.
Çözüm
-İşte tam da bu durumda outbox pattern devreye giriyor ve X servisinin yapacağı işlem ve göndereceği event bir transactional bütünlük içerisinde gerçekleşiyor.
-Eğer event gönderilirken bir sorun ile karşılaşılırsa tüm işlem geri alınıyor. Bu sayede veri bütünlüğü sağlanmış oluyor.
-Ayrıca artık X servisinin eventi yayınlayacağı platforma olan bağımlılığı da ortadan kaldırılmış oluyor. Message Brokerin ayakta olup olmaması artık X servisini ilgilendirmiyor.
-X servisi gerekli veri tabanı işlemlerini tamamladıktan sonra direkt olarak message broker ile iletişime geçmek yerine eventlerin tutulduğu başka bir tabloya kayıt atıyor. Bu şekilde X servisi tüm bu işlemleri transactional bütünlükle yapabiliyor.
-Son olarak da bir message relay(worker service) tabloaya yazılmış olan bu eventleri alıp message brokera yolluyor. Eğer message brokera eventler başarılı bir şekilde gönderilmişse bu tablodaki eventlerin statuleri güncelleniyor.
-Diyelim ki REST Api'mize order requesti geldi.
-İlk olarak apimiz bu isteği alıp Entity tablosuna yazacak.
-Daha sonra Outbox tablosuna kayıt atacak.
-Publisher, Outbox tablosundaki gönderilmemiş statudeki eventleri çekip bu eventleri Event Bus'a gönderecektir.
-Daha sonra Publisher, Event Bus'a gönderdiği kayıtları Outbox tablosundan silecektir. Tamda bu aşamada bir problem çıkarsa ve publisher event busa kayıtları gönderir fakat outbox tablosundan kayıtları silemezse, publisher servisi aynı kayıtları Event busa tekrar göndermiş olacaktır. Artık event busa aynı kayıt iki kez gönderilmiş olacak ve consumer aynı mesajı iki kez almış olacak. Burada oluşan dublicate kayıt sorununu nasıl çözebiliriz ?
Handling Dublicate Messages(Idempotent Consumer)
Dublicate olan messageleri handle etmek için daha önce process ettiğimizi bir tabloya kaydetmemiz gerekir. Consumer ve messageId değeri bir tabloda tutulmalıdır.