Ana içeriğe geç
Zaman Çizelgesi

Engineering Deep Dive

Gerçek üretim ortamındaki optimizasyonlarım, mühendislik kararlarım ve trade-off analizlerim. Bu sayfa, performans ve ölçeklenebilirlik problemlerine yaklaşımımı gösterir.

Architecture Overview

Gerçek üretim ortamında kullanılan temel veri akışının yüksek seviye görünümü.

KAFKASTREAM PROCPOSTGRESREDISAPI GATEWAYCLIENT

Performance Benchmarks

Kafka Consumer Throughput

58k msg/s
12k msg/s
+4.8x Improvement

Batch processing ve asenkron commit optimizasyonu sonrası.

API Response Latency (p99)

65ms
450ms
-85% Improvement

Redis caching katmanı ve N+1 query eliminasyonu.

Docker Image Size

120MB
850MB
-86% Improvement

Multi-stage build ve Alpine base image geçişi.

Optimization Stories

Kafka Backpressure Eliminasyonu

Problem

Burst trafik anlarında consumer lag kontrolsüz artıyor ve rebalance fırtınaları oluşuyordu.

Analysis

Veritabanı yazma hızı, okuma hızının gerisinde kalıyordu. `max.poll.records` varsayılan değeri çok yüksekti.

Solution

Reactive Backpressure (Project Reactor) uygulandı ve batch insert mekanizması devreye alındı.

Result

Lag stabil hale geldi, throughput %40 arttı ve rebalance sorunları bitti.

Bellek Sızıntısı (Memory Leak) Tespiti

Problem

Node.js servisi her 24 saatte bir OOM (Out of Memory) hatasıyla çöküyordu.

Analysis

Heap dump analizi sonucu, kapatılmayan event listener'ların biriktiği görüldü.

Solution

Event emitter kullanımı refactor edildi ve `once` metodu ile otomatik temizlik sağlandı.

Result

Uptime %99.99'a çıktı, bellek kullanımı 200MB'da sabitlendi.

Resilience & Concurrency

INCIDENT LOG
00:00
Traffic spike detected (10x load)
Action: Auto-scaling triggered
New pods spinning up...
00:03
Database latency increased > 2s
Action: Circuit Breaker OPEN
Fail-fast mode active, DB protected
00:07
Cache hit rate dropped
Action: Fallback cache enabled
Stale data served, UX preserved
00:15
Traffic normalized
Action: Circuit Breaker HALF-OPEN
System recovery verified

Code Evolution

N+1 Query Problemi Çözümü

BEFOREjava
// KÖTÜ: Her sipariş için ayrı kullanıcı sorgusu
List<Order> orders = orderRepo.findAll();
for (Order order : orders) {
    User user = userRepo.findById(order.getUserId());
    order.setUser(user);
}
AFTERjava
// İYİ: Tek sorguda tüm kullanıcıları çekme (Eager Fetching)
@EntityGraph(attributePaths = {"user"})
List<Order> findAllWithUser();

// Veya Batch Fetching
List<Order> orders = orderRepo.findAll();
Set<Long> userIds = orders.stream().map(Order::getUserId).collect(toSet());
Map<Long, User> users = userRepo.findAllById(userIds);

İlk yaklaşımda N adet sipariş için N+1 sorgu atılırken, ikinci yaklaşımda sadece 2 sorgu ile tüm veri çekilir.

Trade-off Analysis

Eventual Consistency Seçimi

Pros

  • + Yüksek yazma performansı
  • + Düşük latency
  • + Partition tolerance

Cons

  • - Anlık veri tutarsızlığı
  • - Karmaşık okuma mantığı
"Sosyal medya akışında (feed) anlık tutarlılık kritik değil, ancak hız ve erişilebilirlik (Availability) çok önemli."

Monolith vs Microservices

Pros

  • + Hızlı geliştirme
  • + Kolay deployment
  • + Basit debugging

Cons

  • - Ölçekleme zorluğu
  • - Teknoloji bağımlılığı
"Projenin erken aşamasında (MVP) hız kazanmak için Modüler Monolith tercih edildi. Sınırlar net çizilerek gelecekteki ayrıştırma kolaylaştırıldı."

ENGINEERING DEEP DIVE • NO EXTERNAL API CALLS • STATICALLY GENERATED