Reklam
Reklam
Geçtiğimiz yıl bir müşterinin projesinde danışmanlık yaparken garip bir durumla karşılaştım. Şirket, monolitik sistemlerinden kurtulmak için büyük bir dönüşüm geçirmiş, 8 farklı mikroservise bölünmüş ama deployment süreci 3 saatten 6 saate çıkmıştı. Daha da ilginci, bir servis çökünce diğer 4 servis de çöküyordu. "Biz mikroservise geçtik ama neden hala monolitik gibi davranıyor?" sorusunun cevabı basitti: Dağıtık monolit yaratmışlardı.
Son 5 yılda Türkiye'deki onlarca şirketin mikroservis yolculuğuna tanıklık ettim ve maalesef %70'inin aynı tuzağa düştüğünü gördüm. Bu yazıda, 15 yıllık yazılım geliştirme tecrübemden hareketle, dağıtık monolit denilen mimari anti-pattern'i deşifre edeceğim ve daha da önemlisi, bu durumdan nasıl kurtulacağınızı anlatacağım.
Dağıtık Monolit Nedir? Mikroservisin Kötü Kardeşi
Dağıtık monolit, birbirinden fiziksel olarak ayrılmış görünen ama mantıksal olarak sıkı sıkıya bağlı servislerden oluşan bir mimaridir. Mikroservislerin tüm operasyonel karmaşıklığını yaşarsınız ama monolitik yapının esnekliğinden faydalanamaz hale gelirsiniz.
Bir benzetme yapacak olursam: Büyük bir evi 5 küçük daireye böldünüz ama tüm dairelerin kapılarını birbirine açtınız, elektrik tesisatını ortak bıraktınız ve herkesin aynı mutfağı kullanmasını zorunlu kıldınız. İşte dağıtık monolit tam olarak budur - görünüşte ayrılık, gerçekte tam bir kaos.
Mikroservis Hype'ı: Nasıl Buraya Geldik?
2015-2020 arası dönemde mikroservis mimarisi neredeyse gümüş kurşun olarak pazarlandı. Netflix, Amazon, Uber gibi devlerin başarı hikayelerini dinledik. Türkiye'deki birçok şirket de "biz de modernleşelim" diyerek bu trene atladı. Ancak çoğu, bu devlerin 10 yıllık evrim süreçlerini atlayıp doğrudan son noktaya ulaşmaya çalıştı.
Sonuç? Monolitten kaçarken daha kötü bir yere, dağıtık monolite düştük.
Dağıtık Monolit Olduğunuzu Gösteren 5 Açık Belirti
1. Senkron Bağımlılık Zinciri: Telefon Oyunu Etkisi
Bir kullanıcı sipariş verdiğinde şu akış gerçekleşiyor mu?
- OrderService → CustomerService çağırır (müşteri kontrolü)
- OrderService → ProductService çağırır (stok kontrolü)
- OrderService → PaymentService çağırır (ödeme işlemi)
- OrderService → NotificationService çağırır (bildirim gönderme)
- Her servis diğerinin cevabını senkron olarak bekliyor
Bu klasik bir chain call senaryosudur. Bir servis 200ms gecikirse, tüm işlem o kadar yavaşlar. Daha kötüsü, zincirin herhangi bir halkası koptuğunda tüm sistem çöker.
Geçen sene danışmanlık yaptığım bir e-ticaret firmasında bu zincirleme bağımlılık yüzünden ortalama yanıt süresi 4 saniyeye kadar çıkmıştı. Müşteriler sepeti terk ediyordu çünkü "Sipariş Tamamlanıyor..." ekranı sonsuza kadar dönüyordu.
2. Paylaşımlı Veritabanı: Yanlış Ayrılma
Database per service mikroservislerin temel prensiplerinden biridir. Ancak pratikte şunu çok görüyorum:
- OrderService, CustomerService ve PaymentService aynı PostgreSQL veritabanını kullanıyor
- Hepsi aynı
customerstablosundan okuma/yazma yapıyor - Bir servis tablo şemasını değiştirdiğinde diğer 3 servis çöküyor
Bu durumda mikroservis mimarisinin en önemli avantajını kaybedersiniz: Bağımsız deployment. Bir tabloya yeni bir kolon eklemek için tüm servisleri güncellemeniz gerekir.
Ankara'daki bir fintech startup'ında bu sorunu yaşamışlardı. "Müşteri" tablosuna yeni bir alan eklemek 2 hafta sürmüştü çünkü 7 farklı servisin kodu güncellenmeliydi.
3. Chatty Services: Aşırı Konuşkan Servisler
Mikroservislerin birbirleriyle iletişimi minimize edilmelidir. Ancak dağıtık monolitte şöyle bir durum görürsünüz:
Bir ürün listesi göstermek için:
- 50 ürün için 50 ayrı HTTP çağrısı yapılıyor
- Her çağrı 50ms sürüyor
- Toplam 2.5 saniye sadece network gecikmesiBu durumu İstanbul'daki bir perakende şirketinde yaşadım. Ürün katalog sayfası yüklenmesi 8-10 saniye sürüyordu. Çözüm basitti: Batch API tasarımı ve caching stratejisi. Süreyi 1 saniyenin altına düşürdük.
4. Deployment Korkusu: Hala Birlikte Hareket Ediyoruz
Eğer bir servisi canlıya alırken şunu söylüyorsanız problem var:
"OrderService'i deploy etmeden önce CustomerService ve PaymentService'in yeni versiyonlarını da deploy edelim, yoksa bozulur."
Bu tight coupling (sıkı bağlılık) klasik bir monolit davranışıdır. Mikroservislerin amacı bağımsız deployment sağlamaktır. Her servis kendi hızında, diğerlerini etkilemeden güncellenebilmelidir.
Bursa'daki bir lojistik firmasında bu sorunu Kubernetes üzerinde blue-green deployment ve feature toggle stratejileriyle çözmüştük.
5. Dağıtık Transaction Yönetimi: 2PC Kâbusu
Two-Phase Commit (2PC) protokolü, dağıtık sistemlerde transaction tutarlılığı sağlamak için kullanılır. Ancak yüksek gecikme ve düşük throughput getirir.
Eğer her işleminizde 2PC kullanıyorsanız, mikroservis mimarisinin asıl gücünden faydalanamıyorsunuz demektir. Doğru yaklaşım eventual consistency (nihai tutarlılık) modelini kabul etmek ve saga pattern gibi desenlerle çalışmaktır.
Neden Bu Tuzağa Düşüyoruz? 3 Temel Sebep
1. Yanlış Domain Sınırları: DDD'yi Atlamak
Domain-Driven Design (DDD) mikroservis mimarisinin temelidir. Ancak çoğu ekip teknik katmanlara göre ayırma yapar:
- ❌ UserService, DatabaseService, EmailService (Teknik bölünme)
- ✓ OrderManagement, CustomerManagement, InventoryManagement (İş odaklı bölünme)
Bounded Context kavramını anlamadan mikroservise geçmek, binanın temelini atmadan çatı yapmaya benzer.
İzmir'deki bir SaaS şirketinde Event Storming workshop'ları düzenleyerek doğru bounded context'leri belirledik ve servis sayısını 12'den 5'e düşürdük. Karmaşıklık yarı yarıya azaldı.
2. Conway Yasası'nı Görmezden Gelmek
"Yazılım mimarisi, onu üreten organizasyonun iletişim yapısını yansıtır." - Melvin Conway
Eğer ekipleriniz monolitik organizasyon yapısındaysa, ürettiğiniz mimari de öyle olacaktır. Cross-functional ekipler oluşturmadan mikroservis mimarisine geçmek mantıklı değildir.
3. Teknik Kolaycılık: REST'e Sığınmak
REST API çağrıları alıştığımız, kolay bir yöntemdir. Ancak her servis arası iletişimde senkron REST kullanmak dağıtık monolite giden en hızlı yoldur.
Event-Driven Architecture öğrenmek zaman gerektirir ama uzun vadede sisteminizi ölçeklenebilir kılar. RESTful API Development 2025 rehberimizde modern API tasarımı hakkında detaylı bilgi bulabilirsiniz.
Tedavi: Dağıtık Monolitten Kurtulma Rehberi
1. Domain-Driven Design İlkelerini Uygulayın
Event Storming çalıştayları düzenleyin:
- İş süreçlerini domain event'leri olarak modelleyin
- Aggregate'leri belirleyin
- Bounded context'leri net çizgilerle ayırın
Örnek bir e-ticaret sisteminde:
- Order Context: Sipariş oluşturma, güncelleme, iptal
- Inventory Context: Stok yönetimi
- Payment Context: Ödeme işlemleri
- Notification Context: Bildirim gönderme
Her context'in kendi veritabanı, kendi API'si ve kendi ekibi olmalıdır.
2. Asenkron İletişime Geçin
Event-Driven Architecture mikroservislerin gerçek gücünü açığa çıkarır:
Eski Yöntem (Senkron):
OrderService -> PaymentService.ProcessPayment()
OrderService bekliyor...
PaymentService cevap veriyorYeni Yöntem (Asenkron):
OrderService -> "OrderCreated" event'ini yayınlar
PaymentService event'i dinler ve işler
OrderService işine devam ederTürkiye'de en yaygın kullanılan message broker'lar:
- RabbitMQ: Kurumsal projelerde güvenilir
- Apache Kafka: Yüksek throughput gereken sistemlerde
- Azure Service Bus: Cloud-first yaklaşımda
- Redis Streams: Hafif projelerde alternatif
3. Database Per Service Prensibini Benimseyin
Her servis kendi verisinden sorumlu olmalıdır:
- OrderService → orders_db (PostgreSQL)
- CustomerService → customers_db (MongoDB)
- InventoryService → inventory_db (PostgreSQL)
Veri senkronizasyonu nasıl olacak? Event Sourcing ve CQRS desenleriyle:
- OrderService sipariş oluşturunca "OrderCreated" event'i yayınlar
- CustomerService bu event'i dinler ve kendi veritabanındaki müşteri siparişlerini günceller
- Eventual Consistency kabul edilir
4. API Gateway ve BFF Kullanın
API Gateway, istemci ile mikroservisler arasında tek giriş noktası sağlar:
- Rate limiting
- Authentication/Authorization
- Request routing
- Response aggregation
Backend for Frontend (BFF) deseni ile her istemci tipi için optimize edilmiş API'ler sunabilirsiniz:
- Mobile BFF (daha hafif payload'lar)
- Web BFF (zengin veriler)
- Admin BFF (yönetim işlevleri)
Türkiye'de popüler API Gateway çözümleri:
- Kong: Open-source ve güçlü
- Azure API Management: Cloud entegrasyonu
- AWS API Gateway: Serverless mimarilerde
- Traefik: Kubernetes native
5. Observability: Görünmeyeni Görünür Kılın
Dağıtık sistemlerde hata bulmak çok zordur. Three Pillars of Observability şarttır:
- Logs: Tüm servislerde merkezi loglama (ELK Stack, Loki)
- Metrics: Performans metrikleri (Prometheus, Grafana)
- Traces: İstek akışını takip (Jaeger, Zipkin)
İstanbul'daki bir e-ticaret projesinde Jaeger tracing implementasyonu ile bir bug'ı bulmak 3 günden 20 dakikaya düştü.
15 Yıllık Tecrübeden Altın Notlar
Not 1: Modular Monolith Utanılacak Bir Şey Değil
Geçtiğimiz yıl bir startup danışmanlığında CTO'nun mikroservis ısrarına karşı modular monolith önerisi sundum. İlk başta direniş oldu ama 6 ay sonra "en iyi kararımızdı" dediler.
Modular monolith şu durumlarda mikroservisten daha iyidir:
- Ekip küçükse (10 kişiden az)
- Trafik yoğun değilse (günde 100K istek altı)
- Domain sınırları henüz netleşmemişse
Bir modular monolith, iyi tanımlanmış modüllerle başlayıp gerektiğinde mikroservislere evrilebilir. Shopify bile uzun süre modular monolith kullandı.
Not 2: Maliyet Hesabı Gerçekçi Olmalı
Mikroservislerin gizli maliyetleri vardır:
- DevOps karmaşıklığı: Kubernetes, Helm, CI/CD pipeline'ları
- Monitoring araçları: Aylık binlerce dolar lisans
- Network maliyeti: Servisler arası iletişim AWS'de pahalı olabilir
- Ekip eğitimi: Distributed systems öğrenmek zaman alır
Ankara'daki bir fintech şirketi mikroservise geçince altyapı maliyeti %300 arttı. 2 yıl sonra ölçeklenebilirlik avantajı bu maliyeti karşıladı ama bu süreyi atlayamazdılar.
Not 3: Conway Yasası Her Zaman Kazanır
Organizasyon yapınız mikroservisleri desteklemiyorsa, mimari değişiklik başarısız olur. Şu yapıları sağlayın:
- Product-aligned teams: Feature teams değil, product teams
- You build it, you run it: Ekipler kendi servislerini canlıda yönetmeli
- Inner-source kültürü: Ekipler arası kod paylaşımı ve review
Sonuç Yerine: Mimari, Heves Değil İhtiyaçtır
Dağıtık monolit, yanlış nedenlerle mikroservise geçmenin doğal sonucudur. Eğer sadece "trend olduğu için" veya "CV'ye iyi gözükür" diye mikroservislere geçiyorsanız, bu tuzağa düşmeniz kaçınılmazdır.
Doğru sorular:
- İş gereksinimlerimiz gerçekten mikroservis gerektiriyor mu?
- Ekibimiz dağıtık sistemleri yönetecek olgunlukta mı?
- Operasyonel karmaşıklığı karşılayacak bütçemiz var mı?
Eğer cevaplar "hayır" ise, iyi tasarlanmış bir modular monolith en akıllıca seçimdir.
Son olarak, blog sayfamda modern yazılım mimarisi ve Türkiye'deki gerçek projelerden örneklerle daha fazla içerik bulabilirsiniz.
Sıkça Sorulan Sorular (SSS)
S: Dağıtık monolit ile mikroservis arasındaki farkı nasıl anlarım? C: Bir servisi bağımsız olarak deploy edemiyorsanız, dağıtık monolitsiniz. Gerçek mikroservislerde bir servisin güncellenmesi diğerlerini etkilemez.
S: Türkiye'de mikroservis mimarisine geçen şirketler hangi zorlukları yaşıyor? C: En büyük zorluk DevOps altyapısı eksikliği ve distributed systems konusunda tecrübeli ekip bulamamak. Ayrıca cloud maliyetleri TL bazında yüksek geliyor.
S: Modular monolitten mikroservise geçiş ne kadar sürer? C: Orta ölçekli bir uygulama için 6-12 ay arası. Ancak acele etmeyin, yanlış geçiş daha fazla zaman kaybettirir.
S: Event-driven mimari için hangi aracı önerirsiniz? C: RabbitMQ kurumsal projeler için güvenilir ve Türkçe kaynak bol. Kafka yüksek volume'de tercih edilmeli. Küçük projelerde Redis Streams yeterli olabilir.
S: API Gateway kullanmak zorunlu mu? C: Birden fazla istemciniz varsa (web, mobil, IoT) ve servisleriniz 5'ten fazlaysa API Gateway hayat kurtarır. Aksi halde early optimization olabilir.
Reklam
Reklam

0 Yorumlar