Sinop’taki bir lojistik SaaS firması (TIR + filo takip + faturalama, ~~~~120 müşteri filo), 9 yıllık .NET monolitini 14 ayda 24 mikroservise dönüştürdü. Strangler pattern + service mesh + observability stack ile sahadaki teknik notlar.
Mikroservis Ne Zaman?
| Durum |
Monolit |
Mikroservis |
| Küçük ekip (<10 dev) |
✓ İdeal |
— |
| Büyük ekip (>30 dev) |
— |
✓ İdeal |
| Hızlı MVP |
✓ |
— |
| Bağımsız deploy ihtiyacı |
— |
✓ |
| Farklı tech stack ihtiyacı |
— |
✓ |
| Bağımsız scaling (ör: video processing) |
— |
✓ |
| Fault isolation (bir bug ≠ tüm sistem down) |
— |
✓ |
| Karmaşıklık toleransı |
Düşük |
Yüksek |
Şirket: 28 mühendis, 6 ekip, deploy frequency aylık 2-3 (monolit), scaling sorunlu (video processing CPU yüksek diğerleri ezildi).
Domain Decomposition (DDD)
Bounded context’lere ayırma:
| Bounded Context |
Sahibi |
Servis sayısı |
| Identity & Access |
Platform team |
2 |
| Fleet (araç + sürücü) |
Fleet team |
4 |
| Telemetry (GPS + sensor) |
Telemetry team |
3 |
| Trip (yol planı + tracking) |
Trip team |
4 |
| Billing (fatura + tarife) |
Billing team |
3 |
| Notification (SMS, mail, push) |
Platform |
2 |
| Reporting & Analytics |
Data team |
3 |
| Customer Portal |
Frontend team |
3 (BFF) |
Strangler Fig Pattern
[Müşteri tarayıcı]
↓
[API Gateway (Kong)]
↓
┌───┴────────┐
↓ ↓
[Yeni mikroservis] [Eski monolit]
(kalan endpoint'ler)
Aşamalı:
Hafta 1: Identity servisi çıkar, API Gateway'de route
Hafta 4: Notification çıkar
Hafta 8: Telemetry çıkar (en yüksek CPU yüklü)
...
Hafta 56: Monolit küçüldü → kapatıldı
Service-to-Service Communication
| Pattern |
Kullanım |
| Sync REST |
Query (ör: trip durumu öğren) |
| Sync gRPC |
Yüksek throughput internal |
| Async event (Kafka) |
Domain event (TripStarted, FuelLevelLow) |
| Async command (RabbitMQ) |
İş akışı (BillingRequested) |
Saga Pattern (Distributed Transaction)
Senaryo: Yeni müşteri onboarding
1. Account Service: Müşteri yarat
2. Billing Service: Plan + fatura ayarla
3. Fleet Service: Demo araç bağla
4. Notification: Hoşgeldin mail
Choreography (event-driven):
Account → emit "AccountCreated" event
Billing dinler → "PlanAttached" emit
Fleet dinler → "DemoVehicleAttached" emit
Notification → "WelcomeSent" emit
Compensation:
Eğer Fleet fail → "PlanCanceled" emit + "AccountDeleted" trigger
Service Mesh (Istio)
| Özellik |
Çözüm |
| mTLS (servisler arası encrypt) |
Otomatik |
| Traffic management (canary, A/B) |
VirtualService + DestinationRule |
| Circuit breaker |
OutlierDetection |
| Retry + timeout policy |
VirtualService |
| Rate limit |
EnvoyFilter |
| Observability (golden signals) |
Otomatik metric + trace |
# Canary deployment example
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata: { name: trip-service }
spec:
hosts: [trip-service]
http:
- route:
- destination: { host: trip-service, subset: v1 }
weight: 90
- destination: { host: trip-service, subset: v2 }
weight: 10 # %10 trafik yeni versiyonna
---
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata: { name: trip-service }
spec:
host: trip-service
subsets:
- name: v1
labels: { version: "1.4.2" }
- name: v2
labels: { version: "1.5.0" }
Observability Stack
| Pillar |
Araç |
| Metric |
Prometheus + Grafana |
| Log |
Loki (Grafana stack) |
| Trace |
Tempo (OpenTelemetry) |
| Alert |
Alertmanager → PagerDuty + Teams |
| Dashboards |
Service-specific + RED dashboard |
Distributed Tracing
Trace ID: abc123
→ API Gateway (5ms)
→ trip-service (12ms)
→ fleet-service (8ms)
→ telemetry-service (45ms) ← bottleneck!
→ DB query (38ms) ← root cause
→ billing-service (3ms)
Total: 75ms
Sonuçlar (14 Ay)
| Metrik |
Monolit |
Mikroservis |
| Deploy frequency |
~~aylık 2-3 |
~~günlük 8-12 |
| Lead time (PR → prod) |
~~3 hafta |
~~2 saat |
| MTTR |
~~2 saat |
~~12 dk |
| Change failure rate |
%~~12 |
%~~4 |
| Service availability |
%~~99.4 |
%~~99.91 (granular) |
| Compute cost |
— |
%~~25 daha yüksek (mesh + sidecar overhead) |
| Dev velocity (story/sprint) |
~~22 |
~~38 |
Sahada Düşülen Üç Tuzak
- “Mikroservis cool” diye sorgusuz başlamak: Karmaşıklık yüksek, observability + DevOps olgunluk gerektirir. Küçük ekip için monolit hâlâ doğru olabilir.
- Distributed transaction’ı 2PC ile çözmeye çalışmak: Mikroservis dünyasında 2PC fail. Saga pattern (compensation) düşün.
- Observability’i sona bırakmak: 24 servis arası bug debug observability olmadan kâbus. Day 1 trace + log + metric.
CloudSpark olarak mikroservis mimarisi tasarımı, monolit-mikroservis migrasyonu (strangler), API gateway, service mesh (Istio/Linkerd) ve observability stack için danışmanlık veriyoruz.