Monolitten mikroservise: ne zaman, neden, nasıl
Klavye: ← → ile gezinin, F tam ekran, O genel bakış.
Muhammet Şafak — Görseller
Monolitten mikroservise
Ne zaman, neden, nasıl: sınırı bugün çizin, dağıtımı ölçülmüş bir sinyal gelince yapın.
Muhammet Şafak
Bölüm 01
Sınır
Modüler monolit: tek codebase, tek deploy, tek veritabanı; içeride net modül sınırları.
Üç yaklaşım
Sınır nerede duruyor?
| Yaklaşım | Sınır |
|---|---|
| Klasik monolit | Sınır yok. Her şey her şeye erişir, zamanla "big ball of mud". |
| Mikroservisler | Sınır var, ama sınır aynı zamanda bir network çağrısı. |
| Modüler monolit | Sınır var, ama sınır process içinde; bir method çağrısı. |
Asıl mesele
Sınır ile servis ayrı iki karardır.
Sınırı bugün çizin, dağıtımı gerçekten gerekince yapın.
Sınır kodda
Modül başına tek public yüzey
Bir modül, başka bir modülün yalnızca *Api.php sınıfını çağırır. Başka modülün tablosuna doğrudan SELECT atmaz, foreign key bağlamaz.
1app/2└── Modules/3 ├── Billing/4 │ ├── Domain/ # modüle özel entity, value object5 │ ├── Application/ # use-case'ler6 │ ├── Infrastructure/ # repository, dış servis adaptörü7 │ └── BillingApi.php # modülün TEK public yüzeyi8 ├── Catalog/9 └── Notification/ Neden buradan başlıyorum
Beş somut sebep
- Ucuz düzeltme Yanlış çizilen sınır bir refactor ile düzelir.
- Tek transaction İki modül tek DB transaction'ında tutarlı güncellenir.
- Az operasyon Tek deploy, tek log akışı, izlenecek tek hedef.
- Refactor araçları Bir method çağrısını compiler doğrular.
- Ucuz geçiş Net sınırlı modülü servise çıkarmak mekanik bir iştir.
Disiplin
Sınırı ayakta tutan dört pratik
- Bağımlılık kuralı CI'da; ihlal build'i kırar (deptrac) (tamamlandı)
- Her modülün dışarı açık API'si tek bir sınıf (tamamlandı)
- Modüller arası ilişki foreign key değil, ID + public çağrı (tamamlandı)
- Review sorusu: bu değişiklik bir modül sınırını izinsiz geçiyor mu? (tamamlandı)
Bütün değer disiplinde
CI zorlamıyorsa sınır yoktur.
Sınır CI tarafından zorlanmıyorsa, elinizde modüler monolit değil, sadece klasör isimleri düzgün bir monolit var.
Bölüm 02
Bedel
Mikroservis bir çözüm değil, bir takas.
Tek değişiklik
Method çağrısı network'e döner.
Aldığınız şey bağımsız deploy ve bağımsız ölçekleme. Karşılığında ödediğiniz şey uzun.
Takas
Mikroservisin faturası
| Mikroserviste | Monolitte | |
|---|---|---|
| Çağrı | Serializasyon, latency, partial failure | In-process, ücretsiz |
| Tutarlılık | Saga, outbox, eventual consistency | Tek DB transaction'ı |
| İzleme | Distributed tracing şart | Tek log akışı |
| Deploy | Versiyonlu, geriye uyumlu kontratlar | Tek deploy |
| Refactor | Kimsenin doğrulamadığı kontrat | Compiler doğrular |
Yanlış gerekçeler
Doğru hastalığa yanlış ilaç
| Gerekçe | Asıl çözüm |
|---|---|
| "Kod tabanı çok büyük." | Modül sınırı, dosya düzeni, ölü kod temizliği |
| "Deploy yavaş ve korkutucu." | Hızlı pipeline, test, aşamalı yayın, rollback |
| "Bağımsız ölçeklemem lazım." | Monolit de yatay ölçeklenir: N kopya + load balancer |
| "Modern mimari bu." | Modernlik mimari gerekçe değil |
| "Netflix böyle yapıyor." | Problemi değil, yalnız operasyon yükü kopyalanır |
Kod büyüklüğü
Aynı kod, araya network.
200 bin satırlık bir monolit ile 20 servise bölünmüş 200 bin satır aynı miktarda koddur; ikincisi sadece araya network koymuş hâlidir.
Bölüm 03
Sinyal
Şu sinyallerden en az biri ölçülmüş olmalı.
Ölçülmüş sinyaller
Geçişi haklı çıkaran dört sinyal
- Ölçeklenme profili Bir parça kaynakları geri kalanından bambaşka tüketiyor.
- Sahiplik Ekipler birbirinin deploy'unu bekliyor; sınır organizasyonel.
- Runtime Ölçülmüş darboğaz: iş yükü Go ya da Rust'ta belirgin ucuz.
- Hata izolasyonu Bir modülün çöküşü sistemi düşürmemeli; process içinde sağlanamıyor.
Eşik
Grafikte yoksa sinyal değildir.
Sinyal bir grafikte görünmüyorsa, henüz sinyal değildir.
Bölüm 04
Geçiş
Hepsini değil, sinyali veren tek modülü ayırın.
Strangler kalıbı
Tek modülü dışarı almak
- 1 Adım 1: Modülü seç
sinyali veren tek modül - 2 Adım 2: Servisi kur
yeni servis ayağa kalkar - 3 Adım 3: Trafiği kaydır
çağrılar kademeli yönlenir - 4 Adım 4: Eskiyi sil
eski kod silinir
Ne zaman, ne zaman değil
Ne zaman bölünür, nasıl bölünmez?
- Big-bang Her şeyi aynı anda bölmek en pahalı ve en sık başarısız göçtür.
- Ekip Birden çok ekip aynı deploy biriminde sıkıştığında.
- Kaynak Bir parçanın kaynak profili sistemin geri kalanını rehin aldığında.
- Çöküş Bir bileşenin çöküşü düzenli olarak tüm sistemi düşürdüğünde.
Boring architecture
Karmaşıklık bütçesi sınırlı
- PHP + Laravel ya da Symfony; uygulama katmanı.
- PostgreSQL İlişkisel veritabanı.
- Redis Bellek içi veri deposu.
- Nginx Web sunucusu.
- Linux systemd + Supervisor ile süreç yönetimi.
- Yeni araç Benim eşiğim: boring sayılması için 12–18 ay üretimde aktif kullanım.
Teşekkürler
Sınırları erken çizin, dağıtımı geç yapın. Sinyali bekleyin; kararı moda değil, ölçüm versin.