İçeriğe geç

Yük Dengeleme — Trafik Artınca Kapıya Kim Bakar?

Orta 10 dk Çok sık karşılaşılır

Önce şunu oku: REST Tasarımı ve Idempotency

30 saniyede özet

Tek sunucu yetmeyince servisin kopyaları çalıştırılır ve önlerine trafiği dağıtan bir yük dengeleyici konur. Algoritma yavaşlayanı ne kadar kullanacağını, health check ise öleni ne kadar çabuk fark edeceğini belirler.

Bir banka şubesinde tek gişe açıksa kuyruk kapıya kadar uzar. Yeni gişeler açılınca kapıda biri durup müşterileri boş gişelere yönlendirmeye başlar.

Yük paylaşılır, kapanan gişe atlanır.
Adım adım oku
  1. Tek gişe var; kuyruk kapıya kadar uzamış.
  2. Üç gişe açıldı ve kapıdaki görevli müşterileri aralarında dağıtıyor.
  3. Gişelerden biri kapandı; görevli oraya kimseyi yollamıyor.
  4. Kuyruklar kısa, iş devam ediyor.
  1. Bayt: Pazartesi kampanya başlıyor, trafik on katına çıkacakmış!

  2. Sen: Üç sunucu daha açarız, olur biter.

  3. Bayt: Açarız. Peki gelen istek hangisine gidecek? Biri bozulursa?

  4. Bayt: Kapıdaki görevliyi tanıyalım.

Bir sunucu yetmeyince

Daha güçlü bir makineye geçmek dikey ölçeklemedir: basittir ama bir tavanı vardır ve o makine düşünce her şey durur. yatay ölçeklemeKapasiteyi, aynı servisin daha çok kopyasını çalıştırarak artırmak. Tek makineyi büyütmeye dikey ölçekleme denir.Sözlükte gör → ise aynı servisin kopyalarını çalıştırır.

Kopyaların önünde bir load balancerBir servisin kopyalarının önünde durup gelen istekleri aralarında dağıtan bileşen. Sağlıksız kopyaya trafik göndermemek için onları düzenli olarak kontrol eder.Sözlükte gör → durur. Her isteği kopyalardan birine yollar ve sağlıksız olanı rotasyondan çıkarır.

Tek bir şart var: kopyalar birbirinin yerine geçebilmeli. Oturum bir instance’ın belleğindeyse kullanıcı her istekte başka bir dünyaya düşer; bunu oturum ve stateless ölçekleme dersinde ayrıntılı göreceksin.

Kafam karıştı, daha basit anlat

Tek gişeyi büyütmek yerine yeni gişeler açıyorsun. Hangi müşterinin hangi gişeye gideceğine kapıdaki görevli karar veriyor.

Hızlı kontrolBaşlangıç

Yatay ölçekleme ne demektir?

Cevabı biliyor musun?Önce birini seç. Tekrar zamanlaması buna göre ayarlanıyor.

Bir servisi iki instance'tan altıya çıkarmadan önce neyin doğru olması gerekir?

Cevabı biliyor musun?Önce birini seç. Tekrar zamanlaması buna göre ayarlanıyor.

Sırayla mı, en boşa mı?

En basit algoritma round-robin: A, B, C, sonra yine A. Instance’lar eşitken çok iyi çalışır.

Üç instance'tan B, uzun GC duraklamaları yüzünden yarı hızda çalışmaya başladı ama ayakta. Round-robin B'ye ne kadar trafik gönderir? Least-connections ne yapar? Cevabı göster

Round-robin B’ye yine üçte bir gönderir. B’nin kuyruğu uzar ve oraya düşen her istek yavaşlar. Least-connections her isteği o an en az açık isteği olana verir; B’nin işi birikince yeni istekler kendiliğinden A ve C’ye gider.

least-connectionsHer yeni isteği o an en az açık isteği olan kopyaya veren dağıtım algoritması. Yavaşlayan kopyayı kendiliğinden daha az kullanır.Sözlükte gör → hıza bakmaz, işe bakar: kimde az iş varsa ona verir. Instance’ların güçleri farklıysa ağırlıklı round-robin de kullanılır; güçlü olana daha çok pay düşer.

Kafam karıştı, daha basit anlat

Sırayla yollamak adil görünür ama yavaş gişenin kuyruğunu uzatır. En kısa kuyruğa yollamak yavaş gişeyi kendiliğinden az kullanır.

Hızlı kontrolOrta

Üç instance'tan biri uzun GC duraklamaları yüzünden yarı hızda çalışıyor ama health check'e cevap veriyor. Round-robin kullanan yük dengeleyici ne yapar?

Cevabı biliyor musun?Önce birini seç. Tekrar zamanlaması buna göre ayarlanıyor.

Kim ayakta, kim hazır?

Yük dengeleyici instance’lara düzenli olarak sorar: health check. Cevap vermeyen ya da hata dönen instance birkaç denemeden sonra rotasyondan çıkar. Bir de pasif kontrol vardır: gerçek isteklerde üst üste hata alan instance bir süre dinlenmeye alınır.

Doğru soru, yaşayıp yaşamadığı değil, trafik almaya hazır olup olmadığıdır. Açılışta cache ısıtan bir instance yaşar ama hazır değildir; yük dengeleyici readiness probeKubernetes'in "bu pod şu an trafik almaya hazır mı?" sorusu. Düşerse pod yeniden başlatılmaz, yalnızca load balancer'dan çıkarılır.Sözlükte gör → kontrolüne bakar. Kapanırken de önce readiness düşer ki elindeki istekler bitsin; graceful shutdown dersindeki gibi.

Yük dengeleyiciler iki katmanda çalışır. L4 bağlantıyı IP ve port’a göre dağıtır, içeriği okumaz. L7 HTTP isteğini okur; yola, başlığa ya da cookie’ye göre yönlendirebilir.

Hızlı kontrolOrta

Hangi iş hangi katmanda çalışan bir yük dengeleyici ister?

Cevabı biliyor musun?Önce birini seç. Tekrar zamanlaması buna göre ayarlanıyor.

Sınıflandırılmamış

L4 (TCP)

Bağlantıyı IP ve port'a göre dağıtır, içeriği okumaz

    L7 (HTTP)

    İsteği okur: yol, başlık, cookie

      Yeni açılan bir instance ilk 40 saniye cache ısıtıyor ve bu sürede isteklere yetişemiyor. Yük dengeleyici hangi kontrole bakmalı?

      Cevabı biliyor musun?Önce birini seç. Tekrar zamanlaması buna göre ayarlanıyor.

      Kendin gör

      Üç instance, her tur dört istek. Sağlıklı bir instance tur başına iki istek bitirir. B’ye ne olacağını ve yük dengeleyicinin nasıl davranacağını sen seçiyorsun.

      Trafik üç instance'a nasıl dağılır?

      Tohum 1

      Tur 0 · her tur 4 istek gelir · sağlıklı bir instance tur başına 2 istek bitirir · şu an bekleyen 0

      • Asağlıklı

        bekleyen 0 · biten 0 · kaybolan 0

      • Byavaş ama ayakta

        bekleyen 0 · biten 0 · kaybolan 0

      • Csağlıklı

        bekleyen 0 · biten 0 · kaybolan 0

      Hız
      Adım 0

      Şu an ne oldu?

      Üç instance, saniyede dört istek

      Her instance tur başına iki istek bitirebilir; toplam kapasite gelen trafikten fazla. Bir şey ters gidene kadar.

      Görevler0/3

      • B yavaşken hiçbir isteğin uzun beklemediği bir ayar bulaçık

        İpucu

        Sırayla dağıtmak yerine işin nerede biriktiğine bak.

      • Çöken B'yi rotasyondan çıkaraçık

        İpucu

        Yük dengeleyicinin B'ye düzenli soru sorması gerekir.

      • Çöken instance'ın trafiğin yarısından fazlasını yuttuğunu göraçık

        İpucu

        En boş görüneni seçen bir algoritma, hiç iş tutmayan ölü bir instance'a ne yapar?

      Olay günlüğü (0)

      Henüz olay yok. Oynat veya adımla.

      1. Varsayılanı oynat. Round-robin, B yavaş. Health check açık ama B testten geçiyor; B’nin kuyruğu uzuyor.
      2. Algoritmayı least-connections yap. Aynı yavaş B, ama uzun bekleyen istek yok.
      3. “B çöktü” seç, health check’i kapat. Round-robin’de her üç istekten biri kayboluyor.
      4. Şimdi least-connections’a geç. Çöken B en boş görünüyor ve trafiğin çoğunu yutuyor. Health check’i aç ve farkı gör.
      Hızlı kontrolOrta

      Health check kapalı, algoritma least-connections. B instance'ı çöktü ve gelen her bağlantıyı anında reddediyor. Ne olur?

      Cevabı biliyor musun?Önce birini seç. Tekrar zamanlaması buna göre ayarlanıyor.

      Tuzaklar

      Dış bağımlılığı soran health check. Readiness bütün instance’ların paylaştığı bir dış servise bakarsa, o servis yavaşlayınca hepsi birden “hazır değilim” der. Yük dengeleyici hepsini çıkarır ve bir yavaşlık tam kesintiye döner.

      POST’u tekrar denemek. Zaman aşımına düşen istek başka bir instance’a tekrar gönderilirse havale iki kez yapılabilir. Otomatik tekrar idempotent isteklerle sınırlanır; gerisini idempotency key korur.

      Arkadakiler çarpılır. Her yeni instance kendi bağlantı havuzunu açar: on instance ve yirmişer bağlantı, veritabanına iki yüz bağlantı demektir. Instance eklemeden önce arkadaki kaynağın bunu kaldırıp kaldırmadığına bakılır.

      Kafam karıştı, daha basit anlat

      Health check yalnızca kendi durumunu söylesin. Para hareketini kendiliğinden tekrar deneme. Yeni gişe açarken arkadaki kasanın da yetip yetmediğine bak.

      Hızlı kontrolİleri

      Bu readiness kontrolü eklendikten sonra, ödeme sağlayıcısı bir dakika yavaşladığında bütün servis tamamen erişilemez oldu. Hangi satır?

      Cevabı biliyor musun?Önce birini seç. Tekrar zamanlaması buna göre ayarlanıyor.

      Hatalı satıra dokun, sonra kontrol et.

      ReadinessCheck.java
      Java 21UTF-8LF
      Derinleş · Ödeme API'si: yük dengeleyici, hazır olma kontrolü ve havuz hesabı 3 dosya · ~71 satır · ilk okumada atlayabilirsin
      Proje dosyaları

      deploy/nginx/ payments.conf nginx: least_conn ile en az açık isteği olana gönderir. max_fails ile pasif kontrol yapar: kısa sürede üç hata alan instance bir süre dışarıda kalır. Açık kaynak nginx aktif health check yapmaz; o işi Kubernetes readiness'ı üstlenir.

      deploy/nginx/payments.conf
      upstream payments {
      least_conn;
      # Passive check: three failures within 10s take an instance out for 10s.
      server app-1:8080 max_fails=3 fail_timeout=10s;
      server app-2:8080 max_fails=3 fail_timeout=10s;
      server app-3:8080 max_fails=3 fail_timeout=10s;
      }
      server {
      listen 443 ssl;
      location /api/ {
      proxy_pass http://payments;
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_connect_timeout 1s;
      proxy_read_timeout 5s;
      # Retry on connection errors only; a POST already sent is never sent again (nginx default).
      proxy_next_upstream error;
      }
      }

      src/main/resources/ application.yml Tekrar deneme yalnızca bağlantı hatasında yapılır. nginx, isteği bir kez gönderdiği bir POST'u varsayılan olarak başka bir instance'a tekrar göndermez.

      src/main/resources/application.yml
      server:
      shutdown: graceful
      spring:
      lifecycle:
      timeout-per-shutdown-phase: 20s
      datasource:
      hikari:
      # 3 replicas x 10 = 30 connections to the database. Recheck before adding replicas.
      maximum-pool-size: 10
      management:
      endpoint:
      health:
      probes:
      enabled: true
      group:
      readiness:
      # Only this instance's own state. Shared external services stay out of it.
      include: readinessState

      deploy/k8s/ payments-deployment.yml Spring Boot: readiness grubu yalnızca uygulamanın kendi durumunu içerir; dış servisler buraya girmez. Kapanışta önce readiness düşer, sonra elindeki istekler bitirilir.

      deploy/k8s/payments-deployment.yml
      apiVersion: apps/v1
      kind: Deployment
      metadata:
      name: payments
      spec:
      replicas: 3
      selector:
      matchLabels:
      app: payments
      template:
      metadata:
      labels:
      app: payments
      spec:
      containers:
      - name: payments
      image: bank/payments:1.8.0
      ports:
      - containerPort: 8080
      readinessProbe:
      httpGet:
      path: /actuator/health/readiness
      port: 8080
      periodSeconds: 5
      failureThreshold: 2
      livenessProbe:
      httpGet:
      path: /actuator/health/liveness
      port: 8080
      periodSeconds: 10
      failureThreshold: 3

      Kendini sına

      Önce hızlı bir ısınma: puan yok, kayıt yok. Sonra asıl sorular.

      Şimşek turu1/5

      Dikey ölçekleme, aynı servisin daha çok kopyasını çalıştırmaktır.

      Soru 1/3İleri

      Yük dengeleyici, zaman aşımına düşen istekleri otomatik olarak başka bir instance'a tekrar gönderiyor. POST /transfers için risk nedir?

      Cevabı biliyor musun?Önce birini seç. Tekrar zamanlaması buna göre ayarlanıyor.

      Aklında kalacak üç şey

      1. 1 Yatay ölçeklemenin ön şartı, kopyaların birbirinin yerine geçebilmesidir. Oturum ve dosyalar instance'ın içinde değil, ortak bir yerde durur.
      2. 2 Round-robin sırayla dağıtır ve yavaşlayan instance'a payını vermeye devam eder. Least-connections açık isteğe bakar ve yavaşlayanı kendiliğinden az kullanır.
      3. 3 Health check öleni bulur ama yavaşı bulmaz. Yalnızca instance'ın kendi durumuna bakmalıdır; ortak bir dış bağımlılığı sorarsa bir yavaşlığı tam kesintiye çevirir.
      Sonraki kapı Mesajlar birikiyor, sen de tüketici sayısını ikiye katladın. Neden hiçbir şey hızlanmadı? Kafka — Partition, Consumer Group ve Lag · 10 dk

      5 kart sonraki derste seni bekliyor

      0/4 kart bu dersten toplandı