Event-driven architecture: olay tasarımından dayanıklı işlemeye adım adım
Beceri rehberi

Event-driven architecture: olay tasarımından dayanıklı işlemeye adım adım

Hazırlayan: Mindset Institute EditörlüğüGüncellendi: 6 dk okuma

Olay tabanlı mimari kurulumu: olay tasarımı, üretici ve tüketici, aracı seçimi, outbox ve saga desenleri, idempotency, gözlemlenebilirlik ve sık hatalar.

Olay tabanlı mimari nedir?

Olay tabanlı mimari (event-driven architecture), sistemin parçalarının birbirini doğrudan çağırmak yerine "bir şey oldu" bilgisini olay olarak yayımlaması ve ilgilenen parçaların bu olaya tepki vermesi ilkesine dayanır. Olay, geçmişte gerçekleşmiş bir olgunun kaydıdır: sipariş oluşturuldu, ödeme alındı, stok azaldı. Olayı üreten taraf (üretici) kimin dinlediğini bilmek zorunda değildir; dinleyen taraflar (tüketiciler) olaya kendi ihtiyaçlarına göre tepki verir.

Geleneksel eşzamanlı çağrıda sipariş servisi, ödeme servisini çağırır, yanıt bekler, sonra stok servisini çağırır. Olay tabanlı kurguda sipariş servisi yalnızca siparişin oluştuğunu duyurur; ödeme, stok, bildirim ve raporlama servisleri bunu kendi hızlarında işler. Bağımlılık, servislerin birbirini tanımasından, ortak bir olay sözleşmesine kayar.

Bu yaklaşım bir çözüm değil, bir tasarım tercihidir. Gevşek bağlılık, ölçeklenme ve esneklik sağlar; karşılığında akışın izlenmesini, tutarlılığın yönetimini ve hata ayıklamayı zorlaştırır. Bu dengeyi bilerek seçmek, mimarın temel işidir.

Temel bileşenler: olay, üretici, aracı ve tüketici

Bir olay tabanlı sistemin birkaç temel parçası vardır. • Olay: ne olduğunu, ne zaman olduğunu ve ilgili veriyi taşıyan mesaj. İyi bir olay, geçmiş zamanlı adlandırılır ve tek bir iş olgusunu anlatır. • Üretici (producer): olayı yayımlayan servis. • Olay aracısı (broker): olayları alan, saklayan ve tüketicilere ileten altyapı. Mesaj kuyrukları ve olay akış platformları bu rolü üstlenir. • Tüketici (consumer): olayı okuyup işleyen servis. • Olay şeması: olayın yapısını tanımlayan sözleşme.

Dağıtım modeli açısından temel bir ayrım vardır. Kuyruk modelinde her mesaj tek bir tüketici tarafından işlenir; iş dağıtımı için uygundur. Yayın-abone modelinde aynı olay birçok tüketiciye ulaşır; aynı gerçeğe farklı servislerin tepki vermesi gerektiğinde kullanılır. Olay akışı platformları, olayları kalıcı biçimde saklayıp tüketicilerin kendi hızlarında ve gerekirse geçmişten itibaren okumasına imkân tanır.

Olayları tasarlamak: ne yayımlanmalı?

Mimarideki en kritik beceri, iyi olay tasarlamaktır. Kötü tasarlanmış olaylar, sistemi dağıtık bir karmaşaya çevirir.

Olay türleri arasındaki fark önemlidir. Bildirim olayı yalnızca "sipariş oluştu" der ve ayrıntıyı almak için üreticiye geri dönmek gerekir. Durum taşıyan olay ise ihtiyaç duyulan veriyi içerir, böylece tüketici geri çağrı yapmaz. İlki hafiftir ama bağımlılık yaratır; ikincisi bağımsızlığı artırır ama şema yönetimini ağırlaştırır. Seçim, tüketicilerin ihtiyacına ve verinin hassasiyetine göre yapılır.

Tasarım ilkeleri: • Olayı iş dilinde ve geçmiş zamanda adlandırmak. • Olayı bir iş olgusuna odaklamak; her şeyi içeren büyük olaylardan kaçınmak. • Hassas veriyi olaya koymadan önce düşünmek. • Olay şemasını sürümlemek ve geriye uyumlu tutmak, çünkü tüketiciler üreticiden bağımsız güncellenir. • Olayın benzersiz kimliğini ve zaman bilgisini eklemek.

Şema değişiklikleri için sözleşme yönetimi gerekir: yeni alan eklemek genellikle güvenlidir, alan silmek ya da anlamını değiştirmek tüketicileri bozar.

Sık kullanılan desenler

Olay tabanlı mimaride bazı desenler tekrar eder.

Olay bildirimi: servis, durum değişimini duyurur; diğerleri tepki verir. En yalın desendir.

Olayla durum aktarımı: olay, tüketicinin ihtiyacı olan veriyi taşır ve tüketici kendi yerel kopyasını güncel tutar. Servisler arası sorgu çağrısı azalır.

Olay kaynaklı kayıt (event sourcing): sistemin durumu, olayların sıralı kaydından türetilir. Tüm geçmiş korunur, ama sorgulama ve şema evrimi daha zordur.

Komut ve sorgu ayrımı (CQRS): yazma ve okuma modelleri ayrı tasarlanır; olaylar okuma modelini besler.

Outbox deseni: servis, veritabanı değişikliği ile olay yayımını aynı işlemde güvence altına almak için olayı önce kendi veritabanındaki bir tabloya yazar, sonra ayrı bir süreç yayımlar. Böylece "veri kaydedildi ama olay yayımlanmadı" tutarsızlığı önlenir.

Saga: birden fazla servisi kapsayan iş akışı, olaylar ve telafi adımlarıyla yönetilir. Biri başarısız olursa önceki adımlar geri alınır.

Adım adım örnek: sipariş akışı

Örneğin bir e-ticaret platformunda sipariş akışı olay tabanlı kurulacak olsun.

Sipariş servisi, müşteri onayladığında "sipariş oluşturuldu" olayını yayımlar. Ödeme servisi bu olayı alır, tahsilat dener ve sonuca göre "ödeme alındı" ya da "ödeme reddedildi" olayı yayımlar. Stok servisi ödeme alındıysa ürünü ayırır ve "stok ayrıldı" olayını yayımlar. Bildirim servisi kullanıcıya e-posta gönderir. Raporlama servisi tüm olayları dinleyerek gösterge panosunu besler.

Burada servislerin hiçbiri diğerini doğrudan çağırmaz. Yeni bir ihtiyaç ortaya çıktığında, örneğin sadakat puanı servisi eklenecekse, mevcut servislere dokunmadan yalnızca ilgili olaya abone olmak yeter.

Ama gerçek hayat hata durumlarını da içerir. Ödeme alınmış ama stok yoksa ne olacak? Bu durumda saga mantığıyla telafi olayı yayımlanır ve ödeme iade edilir. Akışın tasarımı mutlu yolla bitmez; hata senaryoları baştan çizilmelidir.

Dayanıklılık: tekrar, sıra ve aynı olayın çift gelmesi

Olay tabanlı sistemlerde ağ ve servis hataları kaçınılmazdır; bu yüzden mesaj dağıtım güvenceleri bilinmelidir. Çoğu aracı, olayın en az bir kez teslim edileceğini taahhüt eder; bu da aynı olayın birden fazla kez gelebileceği anlamına gelir. Tüketici, aynı olayı tekrar işlediğinde zarar vermemelidir. Bu özelliğe eş değerlik (idempotency) denir: örneğin olay kimliğini kaydedip daha önce işlenmişse atlamak.

Sıralama da dikkat ister. Birçok platform sıralamayı yalnızca belirli bir ayrım ya da anahtar kapsamında sağlar. Aynı siparişe ait olayların aynı anahtarla yayımlanması, bu sırayı korumanın yoludur.

Hatalı mesajlar için ölü mektup kuyruğu (dead letter queue) kullanılır: işlenemeyen mesaj ana akışı tıkamaz, ayrı bir yerde incelenir. Geçici hatalar için yeniden deneme, kalıcı hatalar için manuel müdahale yolu tanımlanmalıdır. Tüketici geride kalırsa (gecikme birikimi) bu durum izlenip alarm üretilmelidir.

Gözlemlenebilirlik ve ne zaman tercih edilmemeli?

Olay tabanlı akışlarda tek bir isteğin izini sürmek zordur, çünkü iş birçok serviste asenkron ilerler. İzlenebilirlik için her olaya bir ilişki kimliği (correlation id) konur ve loglarda taşınır. Dağıtık izleme araçları, olayın hangi servislerden geçtiğini görünür kılar. Bunlar sonradan eklenecek bir lüks değil, tasarımın parçasıdır.

Her sistem olay tabanlı olmak zorunda değildir. Anlık yanıt gerektiren, basit istek-cevap işlerinde eşzamanlı çağrı daha yalındır. Küçük ekip ve az sayıda servis varsa, olay altyapısının getireceği operasyonel yük faydayı aşabilir. Tutarlılığın anlık olması gereken işlemlerde (örneğin bakiyeden düşme) dikkatli düşünmek gerekir.

Karar ölçütleri: servislerin bağımsız ölçeklenme ihtiyacı, yeni tüketici ekleme sıklığı, anlık yanıt gerekliliği ve ekibin dağıtık sistem işletme olgunluğudur.

Bu beceriyi Mindset programlarında geliştirmek

API Mimarisinde Asenkron ve Olay Tabanlı Entegrasyon programı asenkron entegrasyonun gerekçesi, mesajlaşma desenleri ve aracılar, webhook ve geri çağrı, olay şeması ve sözleşmeler, gerçek zamanlı kanallar ile dayanıklılık ve gözlemlenebilirlik modüllerinden oluşur.

Mikroservislerde Olay Tabanlı Entegrasyon Desenleri programı ise olay tabanlı mimari temelleri, olay tasarımı ve sözleşme yönetimi, yayınlama garantileri ve outbox, tüketim ile idempotency ve hata yönetimi, dağıtık iş akışı ve tutarlılık, gözlemlenebilirlik ve işletim konularını ele alır.

İlgili Mindset programı

Mikroservislerde Olay Tabanlı Entegrasyon Desenleri

Sık sorulanlar

Sık sorulan sorular

Olay tabanlı mimari ile mesaj kuyruğu aynı şey mi?

Hayır. Mesaj kuyruğu, olay tabanlı mimarinin kullanabileceği bir altyapı bileşenidir. Mimari ise servislerin olaylar üzerinden bağımsız iletişim kurduğu tasarım yaklaşımıdır. Kuyruk iş dağıtımı için de kullanılabilir; olay tabanlı mimari ise daha çok olguların duyurulması ve birçok tüketicinin tepki vermesi üzerine kuruludur.

Olay ile komut arasındaki fark nedir?

Olay geçmişte olmuş bir şeyi anlatır ve kimin dinleyeceğine dair bir beklenti taşımaz: "sipariş oluşturuldu". Komut ise bir servisten bir iş yapmasını ister: "ödemeyi al". Olay, birçok tüketiciye açıktır; komut genellikle belirli bir alıcıya yöneliktir. Karıştırmak mimariyi bulanıklaştırır.

Olay tabanlı mimaride veri tutarlılığı nasıl sağlanır?

Anlık tutarlılık yerine sonunda tutarlılık (eventual consistency) kabul edilir; servisler olaylarla zamanla aynı duruma gelir. Kritik akışlarda outbox deseni, eş değer işleme ve saga ile telafi adımları kullanılır. Hangi işlemin anlık tutarlılık gerektirdiğini baştan belirlemek tasarımın temelidir.

Olay şeması zamanla değişirse tüketiciler ne olur?

Şema değişikliği tüketicileri bozabilir; bu yüzden olaylar bir sözleşme gibi ele alınır. Yeni alanlar eklenir, mevcut alanlar aniden silinmez ya da anlamı değiştirilmez. Şema kayıt araçları uyumluluk kurallarıyla bozucu değişikliği yayımlanmadan yakalar. Köklü bir değişiklikte olayın yeni sürümü yayımlanır, eski sürüm tüketiciler geçene kadar sürdürülür.

Olay tabanlı mimari mikroservislerle mi sınırlıdır?

Hayır. Mikroservislerde yaygın olsa da monolit uygulamalar da modüller arası bağımlılığı azaltmak için iç olaylar kullanabilir. Entegrasyon senaryolarında, örneğin dış sistemlerden gelen bildirimlerde ve gerçek zamanlı veri akışlarında da aynı ilkeler geçerlidir.

Olay Tabanlı (Event-Driven) Mimari Nasıl Kurulur?