Kafka etkinlik akışı, olayları sıralı bir kayıt olarak ele alarak sistem tasarımını değiştirdi. Basit bir kuyruk ne zaman yeterli, log ne zaman avantaj sağlar öğrenin.

OrderPlaced veya PaymentFailed gibi gerçekleri yayınlarsınız; sistemin diğer parçaları ne zaman, nasıl tepki vereceklerine karar verir.\n\nKafka etkinlik akışıyla üreticiler doğrudan entegrasyon listesini tutmak zorunda kalmaz. Checkout servisi bir olay yayınlayabilir ve bunun analytics, e-posta, fraud kontrolleri veya gelecekteki öneri servisi tarafından kullanılıp kullanılmayacağını bilmesine gerek yoktur. Yeni tüketiciler daha sonra ortaya çıkabilir, eskileri duraklatılabilir ve üretici aynı şekilde davranmaya devam eder.\n\nBu aynı zamanda hatalardan kurtulma biçiminizi değiştirir. Sadece mesajlaşmaya dayalı bir dünyada, bir tüketici bir şeyi kaçırdığında veya hatalı çalıştığında veriler sıklıkla “gitmiş” olur; özel yedekler oluşturmadıysanız geri getirilemez. Bir log ile kodu düzeltebilir ve geçmişi yeniden oynatarak doğru durumu yeniden oluşturabilirsiniz. Bu genellikle el ile veritabanı düzenlemelerinden veya güvenilmeyen tek seferlik betiklerden daha iyidir.\n\nPratikte bu değişim birkaç güvenilir şekilde ortaya çıkar: olayları kalıcı kayıt olarak kabul edersiniz, üreticileri değiştirmek yerine abone olarak özellik eklersiniz, okuma modellerini (arama indeksleri, panolar) sıfırdan yeniden inşa edebilirsiniz ve hizmetler arası ne olduğunu gösteren daha net zaman çizelgeleri elde edersiniz.\n\nGözlemlenebilirlik gelişir çünkü olay logu ortak bir referans olur. Bir şey ters gittiğinde iş sırasını takip edebilirsiniz: sipariş oluşturuldu, stok ayrıldı, ödeme yeniden denendi, sevkiyat planlandı. Bu zaman çizelgesi genellikle dağıtık uygulama loglarından daha anlaşılırdır çünkü iş gerçeklerine odaklanır.\n\nSomut örnek: iki saat boyunca bir indirim hatası siparişleri yanlış fiyatlandırdıysa, düzeltmeyi hızla dağıtıp etkilenen olayları yeniden oynatabilir, toplamları yeniden hesaplayabilir, faturaları güncelleyebilir ve analizleri yenileyebilirsiniz. Sonuçları yeniden türetmekle düzeltiyorsunuz, hangi tabloları elle yamalamaya çalışacağınızı tahmin etmekle değil.\n\n## Ne zaman basit bir kuyruk yeterlidir\n\nBasit bir kuyruk işinizi taşımak içindir, uzun vadeli kayıt oluşturmak için değil. Amaç bir görevi bir işçiye teslim etmek, çalıştırmak ve sonra unutmaktır. Kimse geçmişi yeniden oynatmaya, eski olayları incelemeye veya ileride yeni tüketiciler eklemeye ihtiyaç duymuyorsa, kuyruk işleri basit tutar.\n\nKuyruklar arka plan işleri için mükemmeldir: kayıt olma e-postalarını göndermek, yüklemeden sonra resimleri yeniden boyutlandırmak, gece raporu oluşturmak veya yavaş bir dış API'yi çağırmak. Bu durumlarda mesaj sadece bir iş bileti gibidir. İşçi işi bitirince bilet de amacına ulaşmıştır.\n\nKuyruk ayrıca tipik sahiplik modeline uyar: bir tüketici grubu işin uçtan uca sorumluluğunu taşır ve diğer servislerin aynı mesajı bağımsız olarak okuması beklenmez.\n\nAşağıdaki koşulların çoğu doğruysa bir kuyruk genellikle yeterlidir:\n\n- Verinin kısa ömürlü değeri var.\n- Bir ekip veya servis işi baştan sona sahipleniyor.\n- Yeniden oynatma ve uzun tutma gerekleri yok.\n- Hata ayıklama geçmişi yeniden çalıştırmaya bağlı değil.\n\nÖrnek: bir ürün kullanıcı fotoğrafları yüklüyor. Uygulama “resize image” (resmi yeniden boyutlandır) görevi kuyruğa yazar. İşçi A bunu alır, küçük resimleri oluşturur, depolar ve görevi tamamlandı olarak işaretler. Görev iki kez çalışırsa çıktı aynıysa (idempotent), en az bir kez teslimat gayet uygundur. Başka bir servis bu görevi sonra okumaya ihtiyaç duymaz.\n\nİhtiyaçlarınız paylaşılan gerçekler (çoklu tüketiciler), yeniden oynatma, denetim veya “sistem geçen hafta neye inanıyordu?” yönünde kaymaya başlarsa, işte o zaman Kafka etkinlik akışı ve log tabanlı yaklaşım daha çok değeri geri verir.\n\n## Ne zaman log tabanlı yaklaşım avantaj sağlar\n\nLog tabanlı bir sistem, olaylar tek seferlik mesaj olmaktan çıkıp paylaşılan tarihe dönüştüğünde değer verir. "Gönder ve unut" yerine, birçok ekibin kendi hızlarında okuyup daha sonra yeniden oynatabileceği sıralı bir kayıt tutarsınız.\n\nEn net sinyal birden fazla tüketicidir. Bir "OrderPlaced" olayı faturalama, e-posta, fraud kontrolleri, arama indeksleme ve analiz gibi birden fazla sistemi besleyebilir. Log ile her tüketici aynı akışı bağımsız olarak okur. Özel bir fan-out boru hattı kurmanıza veya mesajı önce kim alacak diye koordine etmenize gerek kalmaz.\n\nBir diğer kazanım "o zaman ne biliyorduk?" sorusunu cevaplayabilmektir. Bir müşteri bir ücreti itiraz ederse veya öneri yanlışsa, eklenebilir tarihçe olayların geldiği haliyle yeniden oynatmayı mümkün kılar. Bu denetim izi sonradan basit bir kuyruğa eklenmesi zor bir özelliktir.\n\nAyrıca yeni özellikleri eski parçaları yeniden yazmadan eklemenin pratik bir yolunu elde edersiniz. Aylar sonra yeni bir "gönderim durumu" sayfası eklemek isterseniz, yeni bir servis abone olup geçmişten backfill yaparak durumunu oluşturabilir; tüm üst akım sistemlerden dışa aktarımlar istemek zorunda kalmazsınız.\n\nLog tabanlı yaklaşım genelde şu ihtiyaçlardan biri veya daha fazlası olduğunda değerli olur:\n\n- Aynı olaylar birden fazla sistemi beslemeli (analiz, arama, faturalama, destek araçları).\n- Yeniden oynatma, denetim veya geçmişe dayalı soruşturmalar gerek.\n- Yeni servislerin özel işler yazmadan geçmişten backfill yapması gerek.\n- Varlık başına (sipariş, kullanıcı) sıra önemli.\n- Olay formatları evrilecek ve versiyonlamayı kontrollü ele almanız gerekecek.\n\nYaygın bir örüntü, siparişler ve e-postalarla başlayan bir üründür. Sonra finans gelir ve gelir raporları ister, ürün funnel analizi ister ve operasyon canlı pano ister. Her yeni ihtiyaç sizi yeni bir boru hattı kurmaya zorluyorsa maliyetler hızla görünür olur. Paylaşılan bir olay logu ekiplerin aynı kaynaktan inşa etmesine izin verir ve sistem büyüdükçe olay şekilleri değişse bile ortak bir gerçeğe dayanırlar.\n\n## Karar vermek: adım adım\n\nBasit bir kuyruk ile log tabanlı yaklaşım arasında seçim yapmak, bunu bir ürün kararı gibi ele aldığınızda daha kolaydır. Sadece bu hafta işe yarayan değil, bir yıl sonra geçerli olacak ihtiyaçlara bakın.\n\n### Pratik 5 adımlık karar\n\n1) Yayıncıları ve okuyucuları haritalayın. Bugün kim olay oluşturuyor ve kim onları okuyor yazın; sonra yakın gelecekte olası tüketicileri ekleyin (analiz, arama indeksleme, fraud kontroller, müşteri bildirimleri). Eğer birçok ekibin aynı olayları bağımsız olarak okumasını bekliyorsanız, bir log mantıklı olmaya başlar.\n\n2) Geçmişi tekrar okumanız gerekip gerekmediğini sorun. Nedenini netleştirin: hatadan sonra yeniden oynatma, backfill veya farklı hızlarda okuyan tüketiciler. Kuyruklar işi bir kez devretmek için iyidir. Loglar tekrar oynatma ve kayıt tutma gerektiğinde daha iyidir.\n\n3) “Tamamlandı”nın ne anlama geldiğini tanımlayın. Bazı iş akışları için tamamlandı “işin çalıştırılması” demektir (e-posta gönderildi, resim yeniden boyutlandırıldı). Diğerlerinde tamamlandı “olayın kalıcı bir gerçek olması” demektir (sipariş verildi, ödeme yetkilendirildi). Kalıcı gerçekler sizi loga iter.\n\n4) Teslimat beklentilerini seçin ve çoğaltmaları nasıl ele alacağınızı belirleyin. At-least-once teslimat yaygındır; bu kopyalar olabileceği anlamına gelir. Eğer bir kopya zararlı olabilirse (çift ücretlendirme), idempotentlik planlayın: işlenmiş olay ID'si saklamak, benzersiz kısıtlar kullanmak veya güncellemeleri tekrar uygulanabilir hale getirmek.\n\n5) İnce bir dilimle başlayın. Kolay anlaşılabilir bir olay akışı seçin ve oradan büyütün. Kafka etkinlik akışına karar verirseniz, ilk topic'i odaklanmış tutun, olayları açıkça adlandırın ve ilgisiz olay türlerini karıştırmaktan kaçının.\n\nSomut örnek: OrderPlaced daha sonra gönderim, faturalama, destek ve analizleri besleyecekse, bir log her ekibin kendi hızında okuyup hatalardan sonra yeniden oynatmasına izin verir. Eğer sadece makbuz e-postası gönderecek bir arka plan işine ihtiyacınız varsa, basit bir kuyruk genellikle yeterlidir.\n\n## Örnek: büyüyen bir üründe sipariş olayları\n\nKüçük bir çevrimiçi mağaza hayal edin. İlk etapta sadece sipariş almak, kartı tahsil etmek ve gönderim talebi oluşturmak gerekir. En kolay versiyon, checkout sonrası çalışan bir arka plan işi: “process order.” Bu ödeme API'siyle konuşur, veritabanındaki sipariş satırını günceller ve ardından gönderimi çağırır.\n\nBu kuyruk stili, tek bir iş akışı olduğunda, yalnızca bir tüketici gerektiğinde ve yeniden denemeler ile dead-letter'lar çoğu hata durumunu karşıladığında iyi çalışır.\n\nMağaza büyüdükçe acı başlar. Destek otomatik “siparişim nerede?” güncellemeleri ister. Finans günlük gelir rakamları ister. Ürün ekibi müşteri e-postaları ister. Gönderimden önce bir fraud kontrolü yapılmalı. Tek bir “process order” işiyle aynı işçiyi tekrar tekrar düzenleyip dallar eklemeye başlarsınız ve çekirdek akışta yeni hatalar riski artar.\n\nLog tabanlı bir yaklaşımda checkout küçük gerçekleri olay olarak üretir ve her ekip bunların üzerine inşa edebilir. Tipik olaylar şöyle görünebilir:\n\n- OrderPlaced\n- PaymentConfirmed\n- ItemShipped\n- RefundIssued\n\nAna değişiklik sahipliktir. Checkout servisi OrderPlaced'in sahibidir. Ödeme servisi PaymentConfirmed'in sahibidir. Gönderim ItemShipped'ın sahibidir. Daha sonra yeni tüketiciler üreticiyi değiştirmeden ortaya çıkabilir: fraud servisi OrderPlaced ve PaymentConfirmed'i okuyarak risk skoru hesaplar, bir e-posta servisi makbuzları gönderir, analiz funnel'lar oluşturur ve destek araçları ne olduğuna dair bir zaman çizelgesi tutar.\n\nİşte Kafka etkinlik akışının değeri: log geçmişi saklar, böylece yeni tüketiciler baştan (veya bilinen bir noktadan) geri sarıp yakalayabilir; üreticiden her seferinde yeni bir webhook istemenize gerek kalmaz.\n\nLog veritabanınızın yerini almaz. Hâlâ mevcut durumu sorgulamak için bir veritabanına ihtiyacınız var: en son sipariş durumu, müşteri kaydı, stok sayımları ve işlem kuralları (örneğin "ödeme onaylanmadan gönderme yapma"). Log'u değişikliklerin kaydı, veritabanını ise "şu an ne doğru" sorusunun cevabı olarak düşünün.\n\n## Yaygın hatalar ve tuzaklar\n\nOlay akışı sistemleri daha temiz hissettirebilir, ama birkaç yaygın hata faydaları hızla siler. Çoğu, olay logunu uzaktan kumanda gibi ele almaktan kaynaklanır, oysa log bir kayıt olmalıdır.\n\nSık görülen bir tuzak olayları komut şeklinde yazmaktır, örneğin “SendWelcomeEmail” veya “ChargeCardNow.” Bu tüketicileri niyete sıkı sıkıya bağlar. Olaylar gerçekler olarak daha iyi çalışır: “UserSignedUp” veya “PaymentAuthorized.” Gerçekler zamanla iyi yaşlanır. Yeni ekipler ne demek istediğinizi tahmin etmek zorunda kalmaz.\n\nÇoğaltmalar ve yeniden denemeler bir diğer büyük ağrı kaynağıdır. Gerçek dünyada üreticiler yeniden dener ve tüketiciler yeniden işler. Bunu planlamazsanız çift ücretlendirme, çift e-posta ve mutsuz müşteri servisleriyle karşılaşırsınız. Çözüm egzotik değildir ama kasıtlı olmalıdır: idempotent işleyiciler, sabit olay ID'leri ve “zaten uygulandı”yı tespit eden iş kuralları.\n\nYaygın hatalar:\n\n- Hizmetlere ne yapmaları gerektiğini söyleyen komut tarzı olaylar kullanmak yerine, olanı kaydetmeyle ilgili olaylar yayınlamak.\n- Aynı olayı iki kez görürse bozulan tüketiciler oluşturmak.\n- Tek bir iş akışını çok erken parçalayıp iş akışını çok fazla topic'e yaymak.\n\n- Küçük bir değişiklik eski tüketicileri kırana dek şema kurallarını görmezden gelmek.\n\n- Streaming'i iyi veritabanı tasımının yerine koymak.\n\nŞema ve versiyonlama özel dikkat gerektirir. JSON ile başlasanız bile açık bir sözleşmeye ihtiyacınız var: gerekli alanlar, opsiyonel alanlar ve değişikliklerin nasıl yayılacağı. Bir alanın yeniden adlandırılması gibi küçük bir değişiklik analitikleri, faturalamayı veya yavaş güncellenen mobil uygulamaları gizlice bozabilir.\n\nBir diğer tuzak aşırı bölme yapmaktır. Ekipler bazen her özellik için yeni bir stream oluşturur. Bir ay sonra kimse “Bir siparişin güncel durumu nedir?” diyemez çünkü öykü çok sayıda yerde dağılmıştır.\n\nOlay akışı, sağlam veri modelleri ihtiyacını ortadan kaldırmaz. Hâlâ güncel gerçeği temsil eden bir veritabanına ihtiyacınız var. Log, tüm uygulama değildir; geçmişin kaydıdır.\n\n## Hızlı kontrol listesi ve sonraki adımlar\n\nKuyruk ile Kafka etkinlik akışı arasında seçim yapmakta zorlanıyorsanız, birkaç hızlı kontrolle başlamanız yeterlidir. Bu kontroller size işçi arası basit bir devretme mi yoksa yıllarca yeniden kullanılacak bir log mu gerektiğini söyleyecektir.\n\n### Hızlı kontroller\n\n- Yeniden oynatma (backfill, hata düzeltme veya yeni özellikler için) gerekiyor mu; ne kadar geriye?\n- Aynı olayları birden fazla tüketici şimdi veya yakında mı kullanacak (analiz, arama, e-postalar, fraud, faturalama)?\n\n- Üreticiden tekrar istemeden ekiplerin geçmişi yeniden okuyabilmesi için tutma (retention) gerekli mi?\n\n- Sıralama ne kadar önemli ve hangi düzeyde: varlık başına (sipariş, kullanıcı) mı yoksa gerçekten global mi?\n\n- Tüketiciler idempotent olabilir mi (aynı olayı yeniden uygulamak çift ücretlendirme, çift e-posta veya çift güncelleme yaratmaz mı)?\n\nEğer "hayır" dediniz: yeniden oynatma yok, tek tüketici var ve kısa ömürlü mesajlar söz konusuysa, temel bir kuyruk genellikle yeterlidir. "Evet" dediyseniz: yeniden oynatma, çoklu tüketiciler veya uzun tutma gerekiyorsa, log tabanlı yaklaşım genelde değeri geri verir çünkü tek bir gerçekler akışını diğer sistemlerin üzerine inşa edebileceği paylaşılan bir kaynağa dönüştürür.\n\n### Sonraki adımlar\n\nCevapları küçük, test edilebilir bir plana dönüştürün.\n\n- 5-10 temel olayı açık dille listeleyin (örnek: OrderPlaced, PaymentAuthorized, OrderShipped) ve her birinin kim tarafından yayınlandığını ve kimlerin tüketeceğini not edin.\n- Sıralama anahtarını belirleyin (çoğunlukla varlık başına, örneğin orderId) ve “doğru sıralama”nın ne anlama geldiğini belgeleyin.\n- Her tüketici için idempotentlik kuralı tanımlayın (örneğin: her sipariş için işlenen son olay ID'sini saklamak).\n- İhtiyaçlarınıza uygun bir tutulma hedefi seçin (kuyruk benzeri iş akışları için günler, yeniden oynatma önemliyse haftalar/aylar).\n\n- Karar vermeden önce bir sandbox'ta uçtan uca bir dilim çalıştırın.\n\nHızlı prototip yapıyorsanız, Koder.ai planning modunda olay akışını çizebilir ve tasarımı dağıtmadan önce yineleyebilirsiniz. Koder.ai kaynak kodu dışa aktarma, anlık görüntüler ve geri alma (rollback) desteklediği için bir üretici-tüketici dilimini test etmek ve olay şekillerini ayarlamak için pratik bir yoldur; böylece erken deneyler üretime dönüşen teknik borca dönüşmez.Kuyruk, iş tamamlandıktan sonra unutulmasını istediğiniz iş biletleri (e-posta gönderme, resmi yeniden boyutlandırma, bir işi çalıştırma) için en iyisidir. Kayıt (log) ise saklamak istediğiniz ve birçok sistemin daha sonra okuyup yeniden oynatabileceği olaylar içindir (sipariş verildi, ödeme onaylandı, iade yapıldı).
Bunu şunu hissettiğinizde anlarsınız: her yeni özellik birçok entegrasyonu değiştirmeyi gerektiriyor ve hata ayıklama “bu değeri kim yazdı?” gibi bir çıkmaza dönüşüyor. Bir log, ortak bir kayıt sunduğu için daha iyi: geçmişi inceleyebilir ve gerektiğinde yeniden oynatabilirsiniz.
Aşağıdaki durumlarda değer verir: hatayı düzeltmek için geçmişi tekrar işleme (replay), eski veriden yeni bir özelliği doldurma (backfill), “o zaman ne biliyorduk?” gibi soruşturmalarda cevap almak veya birden fazla tüketici (faturalama, analiz, destek, dolandırıcılık) olduğunda üreticiyi her seferinde değiştirmek zorunda kalmamak.
Çünkü sistemler karmaşık hatalar yapar: tekrarlar, zaman aşımı, kısmi kesintiler ve manuel düzeltmeler. Eğer her servis diğerlerini doğrudan güncelliyorsa, farklı hizmetler olayların sırası hakkında anlaşmazlığa düşebilir. Eklenebilir (append-only) bir olay geçmişi, hangi olayların hangi sırayla geldiğini anlamanıza yardımcı olur; tüketiciler kapalıyken bile daha sonra yakalayabilirler.
Olayları geçmişte olmuş değişiklikler olarak modelleyin ve değiştirilebilir komutlar yerine gerçekleri yayınlayın:\n\n- OrderPlaced, değil ProcessOrder\n- PaymentAuthorized, değil ChargeCardNow\n- UserEmailChanged, değil UpdateEmail\n\nBir şey değişirse, eski kaydı düzenlemek yerine yeni bir olay yayınlayın ve yeni durumu beyan edin.
Çoğu sistemde tekrarlar olacaktır (at-least-once teslimat yaygındır). Her tüketiciyi güvenli hale getmek için:\n\n- Kararlı bir event ID kullanın ve “zaten işlendi” işaretleri saklayın\n- Mümkünse benzersiz kısıtlar uygulayın\n- Aynı olayı tekrar uygulamanın çift yan etki yaratmayacağı şekilde tasarlayın (iki kez ücretlendirme gibi)\n\nVarsayılan kural: önce doğruluk, sonra hız.
Eklemesel (additive) değişiklikleri tercih edin: eski alanları koruyun, yeni alanları opsiyonel ekleyin ve alan yeniden adlandırma/kaldırma gibi değişikliklerden kaçının. Zorunlu olarak geriye dönük uyumsuzluk yapmanız gerekiyorsa, olayı (veya topic/stream’i) versiyonlayın ve tüketicileri planlı şekilde taşıyın.
İnce, uçtan uca bir dilimle başlayın:\n\n1. Tek bir iş akışını seçin (örneğin OrderPlaced → e-posta makbuzu).\n2. Açık olay isimleri ve gerekli alanları tanımlayın.\n3. Sıralama anahtarını seçin (genelde orderId veya userId).\n4. Tüketiciyi idempotent yapın.\n5. Test sırasında yeniden oynatma için yeterli tutulma süresi belirleyin.\n\nDöngünün çalıştığını kanıtlayın, sonra daha fazla olay ve ekip ekleyin.
Hayır. Geçerli durum için bir veritabanı tutmaya devam edin: en son sipariş durumu, müşteri kaydı, stok sayımları ve işlemsel kurallar (örneğin “ödeme onaylanmadan gönderme yapma”). Log değişikliklerin kaydıdır; veritabanı “şu an doğru olan”ı sorguladığınız yerdir. Log, türetilmiş görünümleri yeniden oluşturmak için kullanılır (analiz tabloları, arama indeksleri, zaman çizelgeleri).
Planning modu, yayıncıları/tüketicileri haritalamak, olay isimlerini tanımlamak ve idempotentlik ile tutulma sürelerini belirlemek için faydalıdır. Ardından küçük bir üretici-tüketici dilimi uygulayıp anlık görüntüler (snapshots) alabilir ve geri almayı (rollback) deneyebilirsiniz. Stabil olduğunda kaynak kodunu dışa aktarın ve diğer servisler gibi dağıtın.