YAZILAR / NOTLAR

Kategori: Mimari

Yazılım geliştirme, sistem tasarımı ve karşılaştığım teknik sorunlar üzerine notlar.

WebSocket Tek Sunucuda Kolaydır: Asıl Problem İkinci Node Geldiğinde Başlar

İlk WebSocket implementasyonu genellikle oldukça basittir. Client ↓ WebSocket Server Client bağlanır.Connection bir Map<UserId, Socket> içinde tutulur.Mesaj geldiğinde socket’e gönderilir.Her şey çalışır.Sonra ikinci server instance’ını açarsınız.Problemler orada başlar.Kullanıcı hangi node’da?Architecture artık şöyledir: ┌─ WS Node A Client → LB ─┼─ WS Node B └─ WS Node C Ali Node A’ya bağlı.Ayşe Node C’ye bağlı.Node A’nın […]

AI Kod Yazabiliyor. Peki Mimarinin Dağılmasını Kim Engelleyecek?

AI coding agent’ların en etkileyici tarafı kod yazma hızları. Aynı zamanda en tehlikeli tarafı da bu. Çünkü yanlış bir mimari karar artık yirmi satır değil, birkaç dakika içinde yirmi dosyaya yayılabiliyor. Bu nedenle agent tabanlı geliştirmede asıl problem prompt engineering değildir. Governance engineering’dir. “Best practices kullan” bir gereksinim değildir Bir agente: Clean architecture kullan, production […]

DDD Bir Klasör Yapısı Değildir: Bounded Context’i Yanlış Anladığımız Yer

Bir projenin klasörleri şöyle olabilir: Bu yapı tek başına projeyi Domain-Driven Design yapmaz. Aynı şekilde her modelin yanında Repository interface olması da DDD değildir. DDD’nin asıl değeri kodu hangi klasöre koyduğumuzdan önce sistemi hangi kavramsal sınırlara böldüğümüzde ortaya çıkar. Aynı kelime her yerde aynı şeyi ifade etmeyebilir Bir e-ticaret sisteminde Customer kavramını düşünelim. Sales açısından […]

Queue ile Event Log Aynı Şey Değildir: Kafka ve RabbitMQ’yu Nerede Kullanmalı?

Kafka mı RabbitMQ mu? Bu soru genellikle throughput tablolarıyla cevaplanmaya çalışılıyor. Bence önce farklı bir soru sormak gerekiyor: Gönderdiğimiz şey bir iş mi, yoksa geçmişte gerçekleşmiş bir olay mı? İş yapılacaksa Bir PDF üretilecek olsun. Bir worker mesajı alacak, raporu oluşturacak ve iş tamamlanacak. Başarısızsa retry yapılacak. Belirli sayıda denemeden sonra dead-letter akışına alınabilir. Bu […]

Retry Her Zaman Çözüm Değildir: Timeout, Backoff ve Jitter Neden Birlikte Tasarlanmalı?

Bir servis başka bir servisi çağırdığında başarısızlık normaldir. Network paketi kaybolabilir. Dependency kısa süreli restart olabilir. Database connection pool dolabilir. Bu nedenle retry dağıtık sistemlerin temel araçlarından biridir. Ama yanlış uygulanan retry sistemi iyileştirmek yerine arızayı büyütebilir. Beş servis varsa retry sayısını çarpın Şöyle bir zincir düşünelim: Her katmanın başarısız çağrıyı üç kez retry ettiğini […]

Ödeme API’lerinde Idempotency: Kullanıcı Aynı Ödemeyi İki Kez Yapmasın

Bir ödeme sisteminde en tehlikeli bug’lardan biri uygulamanın çökmesi değildir. Ödeme başarılı olduğu halde uygulamanın başarılı olup olmadığını bilmemesidir. Kullanıcı “Öde” butonuna bastı. Backend bankaya isteği gönderdi. Banka parayı çekti. Tam o anda network bağlantısı koptu. Backend response alamadı. Şimdi ne yapacağız? Tekrar göndermek mantıklı görünür. Fakat ilk işlem başarılıysa müşteriden ikinci kez para çekme […]

Java Virtual Threads: Daha Fazla Thread Değil, Farklı Bir Concurrency Modeli

Java dünyasında yıllarca thread sayısı pahalı bir kaynak olarak düşünüldü. Bu nedenle thread pool boyutları, queue capacity ve executor tuning backend geliştirmede önemli optimizasyon alanlarından biri haline geldi. Project Loom ile gelen Virtual Threads bu varsayımı ciddi biçimde değiştirdi. Virtual Threads, Java 21 ile JEP 444 kapsamında kalıcı özellik haline geldi. OpenJDK’nin amacı özellikle thread-per-request […]

Redis Eklemek Performans Problemini Çözmez: Cache Tasarımında Asıl Zor Kısım

Cache hızlıdır. Cache tasarımı ise zordur. Bir endpoint yavaşladığında en kolay önerilerden biri şudur: Redis koyalım. Bazen gerçekten doğru çözümdür. Ancak cache eklemek problemi çözmek yerine sisteme yeni bir consistency problemi de ekleyebilir. Çünkü asıl soru veriyi Redis’e nasıl koyacağınız değil, hangi veriyi ne kadar süreyle doğru kabul edeceğinizdir. En sık kullanılan modellerden biri cache-aside’dır. […]

Mikroservis Bir Hedef Değildir: Modüler Monolit Ne Zaman Daha Doğru Seçim?

Mikroservis Bir Hedef Değildir Bir yazılım projesi büyümeye başladığında mimari konuşmalarının mikroservislere gelmesi neredeyse kaçınılmaz. Servislerin bağımsız deploy edilmesi, ayrı ayrı ölçeklenebilmesi ve ekiplerin birbirinden bağımsız hareket edebilmesi oldukça cazip. Sorun şu: mikroservislerin avantajlarını almak için önce dağıtık sistemlerin maliyetini kabul etmek gerekir. Aynı process içindeki bir metod çağrısını başka bir servise taşıdığınız anda artık […]