Blog'a dön
•
ByteGurus

Mikroservis Mimarisinde İyi Uygulamalar

Mikroservis mimarisinde servis sınırları, API sözleşmeleri, servis başına veri, olay güdümlü iletişim, gözlemlenebilirlik ve dayanıklılık kalıpları.

Mikroservisler Mimari Kubernetes DevOps

Mikroservis mimarisi, tek parça (monolit) bir uygulamayı bağımsız geliştirilip dağıtılabilen küçük servislere ayırır. Doğru kurulduğunda ekipler birbirini beklemeden çalışır, sistem parça parça ölçeklenir ve bir hata tüm uygulamayı düşürmez. Yanlış kurulduğunda ise dağıtık bir monolit elde edersiniz: tek parçanın bütün zorlukları, ağın bütün sorunlarıyla birlikte. Bu yazı farkı yaratan uygulamaları sıralıyor.

Neden mikroservis

Monolit büyüdükçe tek kod tabanı geliştirmede, testte ve dağıtımda darboğaza döner: küçük bir değişiklik bütün uygulamanın yeniden test edilip yayınlanmasını ister. Mikroservisler, ekiplerin kendi servislerini diğerlerini etkilemeden geliştirip yayına almasını sağlar. Bedeli dağıtık sistemin karmaşıklığıdır; bu yüzden aşağıdaki uygulamalar isteğe bağlı değildir.

1. Servisleri iş yeteneklerine göre ayırın

Servis sınırını teknik katmanlar değil, iş alanları belirler.

Yanlış: teknik katmana göre

  • Veritabanı servisi
  • Önbellek servisi
  • API servisi

Doğru: iş yeteneğine göre

  • Kullanıcı yönetimi
  • Sipariş işleme
  • Ödeme

Her servis kendi alan mantığının ve verisinin sahibidir. Bu, alan güdümlü tasarımın (Domain-Driven Design) sınırlı bağlam (bounded context) kavramına karşılık gelir. İyi bir sınırın işareti şudur: bir iş kuralı değiştiğinde yalnız bir servis değişir.

2. API sözleşmelerini açık ve sürümlü tutun

Servisler REST, gRPC ya da olaylar üzerinden açıkça tanımlanmış sözleşmelerle konuşur. Sözleşme kodla birlikte bir yerde yazılı durur (OpenAPI, Protocol Buffers) ve baştan sürümlenir:

// orders/v1/order.proto
message Order {
  string id = 1;
  string customer_id = 2;
  OrderStatus status = 3;
  int64 total_minor = 4;   // kuruş cinsinden
  string currency = 5;
}

Alan eklemek geriye uyumludur; alan silmek ya da anlamını değiştirmek yeni sürüm demektir. Böylece bir servisin güncellenmesi diğerlerini kırmaz.

3. Her servis kendi verisinin sahibi olsun

Servisler arasında ortak veritabanı, görünmeyen bağımlılıkların en yaygın kaynağıdır.

İlkeler:

  • Bir servis başka bir servisin veritabanına doğrudan erişmez
  • Veri paylaşımı API ya da olay üzerinden olur
  • Her servis kendi ihtiyacına uyan veritabanını seçebilir
  • Servisler arası tutarlılık nihai tutarlılık ve saga kalıbıyla sağlanır

Bir servisin başka bir servisin verisine sık ihtiyacı varsa, her seferinde senkron çağrı yapmak yerine o servisin yayınladığı olaylardan kendi yerel kopyasını (projeksiyon) tutması çoğu zaman daha dayanıklıdır: karşı servis kapalıyken de çalışmaya devam eder.

4. Servis keşfi

Servisler dinamik olarak açılıp kapandığı için birbirini sabit adreslerle bulamaz. Kubernetes bunu yerleşik olarak çözer (Service ve DNS); Kubernetes dışında Consul ya da etcd gibi araçlar kullanılır. Kubernetes kullanıyorsanız ek bir keşif aracına çoğu zaman ihtiyacınız olmaz.

5. Senkron ve asenkron iletişimi ayırın

Her servis çağrısı senkron olmak zorunda değildir.

Senkron (istek-cevap): cevabın o anda gerektiği durumlar; örneğin ekranda gösterilecek bir sorgu.

Asenkron (olay güdümlü): cevap beklenmeyen işler; bildirim göndermek, analitiği güncellemek, başka servislerin durumunu tetiklemek.

from confluent_kafka import Producer
import json

producer = Producer({"bootstrap.servers": "kafka:9092", "enable.idempotence": True})

event = {
    "event_type": "order_created",
    "order_id": "12345",
    "occurred_at": "2026-01-15T10:30:00Z",
}
# Aynı siparişin olayları aynı anahtarla gider: bölüm içinde sıra korunur
producer.produce("orders", key="12345", value=json.dumps(event))
producer.flush()

Olayı veritabanı kaydıyla aynı transaction’da bir outbox tablosuna yazmak, kayıt ile olayın birbirinden kopmasını engeller.

6. Gözlemlenebilirliği baştan kurun

Çok parçalı bir sistemde merkezi kayıt, metrik ve dağıtık izleme olmazsa olmazdır.

  • Kayıt: Loki, ELK, bulut sağlayıcısının kayıt servisi
  • Metrik: Prometheus ve Grafana
  • İzleme: OpenTelemetry ile Jaeger ya da Tempo

Her isteğe bir iz kimliği verin ve bunu servisler arasında taşıyın; kayıtları yapılandırılmış (JSON) yazın:

{
  "timestamp": "2026-01-15T10:30:00Z",
  "trace_id": "4bf92f3577b34da6a3ce929d0e0e4736",
  "service": "order-service",
  "level": "INFO",
  "message": "Sipariş işleme başladı",
  "order_id": "12345"
}

7. Konteyner orkestrasyonu

Konteynerler ve Kubernetes dağıtımı, ölçeklemeyi ve işletmeyi standartlaştırır:

  • Yüke göre otomatik ölçekleme
  • Çöken konteynerin kendiliğinden yeniden başlaması
  • Kesintisiz kademeli güncelleme
  • Kaynak sınırları ve servis ağı entegrasyonu

8. Dayanıklılık kalıpları

Dağıtık sistemde ağ her zaman bir gün hata verir. Bunun için:

  • Zaman aşımı: her servis çağrısında; zaman aşımı olmayan çağrı, kaynakları sonsuza dek tutar
  • Yeniden deneme: üstel bekleme ve rastgele sapmayla (jitter), yalnız idempotent işlemlerde
  • Devre kesici (circuit breaker): sürekli hata veren servise istek göndermeyi bir süre keser
  • Bölmeler (bulkhead): bir bağımlılığın sorunu tüm kaynakları tüketmesin diye havuzları ayırır

.NET’te Polly, Java’da Resilience4j bu kalıpları hazır sunar; servis ağı da bir kısmını altyapı düzeyinde uygular.

9. Veri tutarlılığını planlayın

Servisler arası dağıtık transaction pahalıdır ve kırılgandır. Bunun yerine:

Saga: çok adımlı bir iş akışı, her adımın başarısızlıkta geri alınmasını sağlayan telafi adımlarıyla birlikte yürütülür. Koreografi (olaylarla) ya da orkestrasyon (merkezi bir koordinatörle) kurulabilir.

Olay kaynaklama: durum değişiklikleri değiştirilemez olaylar olarak saklanır; tam bir denetim izi verir ama her servis için gerekli değildir.

10. DevOps kültürü

Mikroservisler işletme olgunluğu ister:

  • Altyapının kod olarak yönetilmesi (Terraform, OpenTofu)
  • Sürekli entegrasyon ve dağıtım
  • Her düzeyde otomatik test, özellikle sözleşme testleri
  • Kademeli yayın için özellik bayrakları
  • Servisin geliştirmeden üretime kadar sahibi olan ekipler

Dikkat edilecekler

Conway yasası: sistemin yapısı, onu kuran kurumun iletişim yapısını yansıtır. Servis sınırlarını ekip sınırlarıyla birlikte düşünün.

Erken bölmeyin: alanınız henüz netleşmediyse iyi modüllere ayrılmış bir monolitle başlayın. Sınırlar oturduktan sonra servisleri ayırmak, yanlış çizilmiş servis sınırlarını birleştirmekten çok daha kolaydır.

Güvenlik: servisler arası kimlik doğrulama (mTLS), istekleri doğrulayan bir API geçidi ve sır yönetimi. Kimlik bilgileri asla koda yazılmaz.

Sonuç

Mikroservisler, düşünülerek kurulduğunda ölçeklenebilir ve bakımı kolay sistemler verir. Başarı net servis sınırlarına, sağlam iletişim kalıplarına, baştan kurulmuş gözlemlenebilirliğe ve işletme olgunluğuna bağlıdır. İş alanından başlayın, temeli sağlam kurun, gerçek deneyime göre geliştirin.

Mikroservis mimarinizi birlikte değerlendirmek isterseniz bize yazın.

B

ByteGurus

Yazar

Tüm yazılara dön
Başlamaya hazır mısınız?

Projenize başlamaya hazır mısınız?

Fikirlerinizi hayata geçirmek için size nasıl yardımcı olabileceğimizi konuşalım.