Bir üretim ERP’sinin sevkiyat modülünü yazarken, sırf o dönem moda diye her şeyi mikroservislere bölmeye karar vermiştik. Sonuç ne mi oldu? Bir gece yarısı, ağdaki anlık bir MTU uyuşmazlığı yüzünden faturayı kesen servis ile stok düşen servis birbirini bulamadı; veri tutarsızlığı yüzünden üretim hattı saatlerce durdu.
O sabah kahve bardağını masaya vurup “Biz ne yapıyoruz?” dediğimi dün gibi hatırlıyorum. Kod yazmak yerine network paketlerini izliyor, servisler arası kimlik doğrulamayı çözmeye çalışıyor ve distributed transaction yönetmek için takla atıyorduk. İşte o gün, monolith mimarinin kıymetini ve bize kaybettirilen sadeliği yeniden keşfettim.
Trendlerin Peşinde Kaybolan Akıl
Sektörde son on yıldır öyle bir hava estirildi ki, monolith yazan yazılımcılara sanki mağara devrinde kalmış gibi bakılmaya başlandı. Konferanslarda, bloglarda herkes Netflix ölçeğindeki sistemlerden bahsedip mikroservis güzellemesi yaptı. Ben de bu furyaya kapılıp birkaç projede gereksiz yere sistemleri parçaladım ve her seferinde aynı duvara tosladım.
Mikroservis mimarisi teknik bir zorunluluktan ziyade, yüzlerce geliştiricinin çalıştığı devasa organizasyonların yönetimsel sorunlarını çözmek için doğdu. Eğer 10-15 kişilik bir ekipseniz veya tek başınıza bir yan ürün geliştiriyorsanız, mikroservis kullanmak kendi ayağınıza kurşun sıkmaktan farksızdır. Network overhead, serialization maliyetleri ve veri tutarlılığı (eventual consistency) gibi tonla yapay problemle uğraşmak zorunda kalırsınız.
# Monolith'te transaction yönetimi basittir
with database.transaction():
create_invoice(order_id)
decrease_stock(product_id)
# Bir hata olursa her şey otomatik olarak rollback edilir
Yukarıdaki basit kod bloğu, monolith içinde tek bir veritabanı bağlantısıyla milisaniyeler içinde güvenle çalışır. Aynı işlemi mikroservisler arasında yapmaya kalktığınızda Saga Pattern, Outbox Pattern veya iki aşamalı commit (2PC) gibi sistemleri kurmanız gerekir ki bu da hata payını katlar.
Tek Bir Veritabanı, Tek Bir Proses: Sadelikten Gelen Güç
Kendi geliştirdiğim ve saniyede yüzlerce istek alan bir finansal hesaplayıcı yan ürünümün backend’ini tamamen monolith olarak tasarladım. Tek bir PostgreSQL veritabanı, önünde Nginx reverse proxy ve FastAPI üzerinde koşan tek bir monolith prosesi var. Her şeyi tek bir sunucu içinde, Docker Compose ile yönetiyorum ve sistem saat gibi tıkır tıkır çalışıyor.
Veritabanı indexlerini (B-tree ve BRIN) doğru yapılandırdığınızda, PostgreSQL’in connection pool ayarlarını düzgün yaptığınızda tek bir veritabanı sizi tahmin edemeyeceğiniz kadar ileriye taşır. Dağıtık sistemlerin getirdiği o “network gecikmesi” monolith’te yoktur çünkü veriler hafızada veya yerel ağda çok daha hızlı döner.
Dağıtık Sistemlerin Gizli Faturaları
Mikroservislere geçtiğinizde sadece kodunuzu bölmezsiniz; operasyonel yükünüzü de en az beş katına çıkarırsınız. Eskiden systemd altındaki tek bir log dosyasından (journald) hatayı bulabilirken, şimdi dağıtık log izleme (distributed tracing) araçları kurmak zorunda kalırsınız. Hatanın hangi serviste başladığını, hangi HTTP isteğiyle yayıldığını bulmak tam bir dedektiflik işine dönüşür.
Danışmanlık verdiğim bir firmada, API gateway arkasındaki çok sayıda servisin birbirini çağırma zinciri yüzünden oluşan gecikmeyi (latency) çözmek günlerimi aldı. Sorun ne koddaydı ne de veritabanında; tamamen servisler arası gereksiz ağ trafiğinden kaynaklanıyordu. Sistemi birkaç kritik monolith parça halinde birleştirdiğimizde gecikme süresi belirgin biçimde düştü.
Ne Zaman Ayrılmalı? (Gerçekçi Bir Sınır)
Ben monolith fanatiği de değilim, her soruna monolith ile vurulmalı demiyorum. Eğer sisteminizin bir parçası (örneğin resim işleme veya ağır AI planlama algoritmaları) CPU’yu çok fazla tüketiyor ve uygulamanın geri kalanını yavaşlatıyorsa, sadece o kısmı ayırıp bağımsız bir servis yapabilirsiniz. Buna “Modüler Monolith” diyoruz ve bence şu anki en sağlıklı mimari yaklaşım bu.
Modüler monolith tasarlarken kod tabanınızı klasörler ve bağımsız modüller halinde temiz tutarsınız. Yarın bir gün gerçekten bir modülü ayırmak gerekirse, sınırları zaten belli olduğu için onu mikroservise dönüştürmek görece kolay olur. En baştan her şeyi bölüp network karmaşasına boğulmaktansa, monolith ile başlayıp acı çektikçe büyümek her zaman daha az maliyetlidir.
Peki ya sen? Sırf “trend” diye girdiğin mikroservis macerasında hiç sabahladın mı, yoksa monolith sadeliğinin kıymetini bilenlerden misin? Yorumlarda tartışalım.