---
title: 'Yük Boşaltma'
source: 'https://academia.sh/tr/kurslar/eszamansiz-isleme/yuk-bosaltma'
course: 'Önbellekleme, Kuyruklar ve Eşzamansız İşleme'
language: tr
updated: '2026-08-17T18:06:46+00:00'
license: 'CC BY-SA 4.0'
---

# Yük Boşaltma

Aşırı yükte denetimli reddetme: eşzamanlılık eşiğine dayalı kabul denetimi, kabul edilenle reddedilenin gecikme farkının ölçümü, reddin HTTP'deki biçimi ve yeniden deneme fırtınasının önlenmesi.

Bir önceki ders geri basıncı kurdu ve bir sınırla bitti: geri basınç sistemin iç
halkalarında çalışır, dış ucunda duran istemciye taşınamaz. İstek işleyen bir sunucu,
arka plan kuyruğu dolduğu için isteği süresiz bekletemez.

O zaman aşırı yükte ne yapılır. Yanıt, kabul edilmesi güç olduğu için sık atlanır:
**isteği reddetmek**. Reddetmek bir arıza değil, bir tasarım kararıdır. Reddetmeyen bir
sunucu istekleri kabul etmeye devam eder, her birinin gecikmesi büyür ve bir noktadan
sonra hiçbir istek zamanında karşılanmaz. Bu duruma **çöküş** denir ve reddetmekten çok
daha kötüdür: reddedilen istek en azından hızlıca reddedilmiştir. Bu ders reddin nasıl
denetimli yapılacağını kurar ve iki durumun gecikmesini ölçerek karşılaştırır.

## Kabul Denetimi

**Yük boşaltma** (load shedding), sistemin kapasitesini aşan işi kabul etmeyip geri
çevirmesidir. Kararı veren yapıya **kabul denetimi** (admission control) denir ve iş
başlamadan **önce** çalışır.

Kabul denetimi, hız sınırlamadan iki noktada ayrılır. Hız sınırlama belirli bir
istemcinin belirli bir sürede yapabileceği istek sayısını sınırlar; ölçütü istemcidir ve
amacı adil paylaşımdır. Kabul denetiminin ölçütü ise **sistemin o anki durumudur**;
amacı, kabul edilmiş işlerin zamanında bitmesini korumaktır. Aynı istemci, sistem boşken
kabul edilir, doluyken reddedilir.

### Eşik Neye Konur

Eşiğin saniyedeki istek sayısına konması yaygın ama yanıltıcıdır. Saniyedeki istek sayısı
işin süresini içermez: aynı hız, iş yirmi milisaniye sürüyorsa rahat, üç yüz milisaniye
sürüyorsa taşırıcıdır.

Doğru ölçüt **eşzamanlılıktır**: aynı anda işlenen iş sayısı. Önceki derste kullanılan
$L = \lambda W$ bağıntısı bunu doğrudan verir; sistemdeki iş sayısı $L$ sabitlenirse,
ortalama süre $W$ de sabitlenmiş olur. Eşzamanlılığı sabitlemek gecikmeyi sabitlemektir.

Aşağıdaki sunucu iki eşik taşır: aynı anda işlenebilecek iş sayısı ve kuyrukta
bekleyebilecek iş sayısı. İkisinin toplamı, sistemin kabul ettiği en büyük yüktür.

```js
// kabul.mjs — is sunucusu; iki kipte calisir
//   node kabul.mjs --sinirsiz    gelen her istek kuyruga alinir
//   node kabul.mjs --denetimli   esik asilinca istek 503 ile geri cevrilir
import { createServer } from "node:http";

const DENETIMLI = process.argv.includes("--denetimli");
const EN_COK_ESZAMANLI = 2;        // ayni anda islenen is sayisi
const EN_COK_KUYRUK = 2;           // kuyrukta bekleyebilecek is sayisi
const IS_SURESI = 300;             // bir isin suresi (ms)

let calisan = 0;
const kuyruk = [];

const isYap = () => new Promise((c) => setTimeout(c, IS_SURESI));

async function baslat(gorev) {
  calisan++;
  await isYap();
  calisan--;
  gorev.yanit.writeHead(200, { "content-type": "text/plain" });
  gorev.yanit.end(`${gorev.durum}\n`);
  const sonraki = kuyruk.shift();
  if (sonraki) baslat(sonraki);
}

createServer((istek, yanit) => {
  yanit.sendDate = false;
  if (calisan < EN_COK_ESZAMANLI) return baslat({ yanit, durum: "kabul" });
  if (!DENETIMLI || kuyruk.length < EN_COK_KUYRUK)
    return kuyruk.push({ yanit, durum: "kuyruk" });
  // Esik asildi: istek beklemeye alinmaz, ne zaman tekrar denenecegi bildirilir.
  yanit.writeHead(503, { "content-type": "text/plain", "retry-after": "1" });
  yanit.end("bosaltildi\n");
}).listen(8352, "127.0.0.1", () => console.log("dinleniyor: 127.0.0.1:8352"));
```

## Ölçüm

Aşağıdaki betik sunucuyu iki kipte de ayağa kaldırır, her seferinde on isteği aynı anda
gönderir ve sonuçları durum koduna ve yüz milisaniyelik gecikme dilimlerine göre
gruplar. Bağlantı noktası 8352 keyfîdir ve boş olmalıdır.

```bash
#!/usr/bin/env bash
# kabul.mjs'yi iki kipte baslatir, her kipte on istegi ayni anda gonderir, sonucu ozetler.
A=http://127.0.0.1:8352

olc() {
  node kabul.mjs "$1" > /dev/null & sunucu=$!
  sleep 1
  pid=()
  for i in $(seq 1 10); do
    curl -sS -o /dev/null -w '%{http_code} %{time_total}\n' "$A/is" & pid+=($!)
  done > ham.txt 2>&1
  wait "${pid[@]}"
  echo "--- $2 ---"
  awk '{ printf "durum=%s  gecikme=%2d dilim\n", $1, int($2 * 10) }' ham.txt | sort | uniq -c
  kill "$sunucu"
  sleep 0.5
}

olc --sinirsiz  "kabul denetimi yok: her istek kuyruga alinir"
olc --denetimli "kabul denetimi var: esik asilinca 503"
```

```
--- kabul denetimi yok: her istek kuyruga alinir ---
   2 durum=200  gecikme= 3 dilim
   2 durum=200  gecikme= 6 dilim
   2 durum=200  gecikme= 9 dilim
   2 durum=200  gecikme=12 dilim
   2 durum=200  gecikme=15 dilim
--- kabul denetimi var: esik asilinca 503 ---
   2 durum=200  gecikme= 3 dilim
   2 durum=200  gecikme= 6 dilim
   6 durum=503  gecikme= 0 dilim
```

Dilim sayısı yüz milisaniyelik birimdir; iş süresi üç yüz milisaniye olduğu için ilk çift
üç dilimde, ikinci çift altı dilimde yanıt alır. Yavaş bir makinede dilim sayıları bir
üste kayabilir.

İki kip aynı işi yapıyor, ama gecikme dağılımları taban tabana zıt.

Denetimsiz kipte **hiçbir istek reddedilmedi** ve kimse memnun olmadı: son iki istek bir
buçuk saniye bekledi. Yük on yerine yüz istek olsaydı son isteğin gecikmesi on beş saniye
olurdu. Kabul edilen her istek, kendinden önce kabul edilmiş herkesin gecikmesini
taşıyor.

Denetimli kipte dört istek karşılandı, altısı **sıfırıncı dilimde**, yani bekletilmeden
reddedildi. Kabul edilenlerin gecikmesi üç ve altı dilimde kaldı; sistem, kabul ettiği
isteklere verdiği sözü tuttu.

Fark tek cümleyle şudur: kabul denetimi, **belirsiz bir gecikmeyi kesin bir redde**
çevirir. İstemci için bu iyileşmedir, çünkü redde karşı bir davranışı vardır — yeniden
denemek, işi ertelemek, kullanıcıya bilgi vermek. Belirsiz bir beklemeye karşı hiçbir
davranışı yoktur.

## Reddin Biçimi

Reddin nasıl bildirildiği, reddedilme kararı kadar önemlidir. Aşağıdaki betik sunucuyu
doygunluğa getirip bir isteğin ham yanıtını gösterir.

```bash
#!/usr/bin/env bash
# Doygunluga ulasmis sunucudan gelen reddin yanitini basliklariyla gosterir.
node kabul.mjs --denetimli > /dev/null & sunucu=$!
sleep 1
A=http://127.0.0.1:8352

pid=()
for i in 1 2 3 4; do curl -sS -o /dev/null "$A/is" & pid+=($!); done   # 2 calisan + 2 kuyruk
sleep 0.1
echo "--- doygunlukta gelen istegin yaniti ---"
curl -sS -D - "$A/is"
wait "${pid[@]}"
kill "$sunucu"
```

```
--- doygunlukta gelen istegin yaniti ---
HTTP/1.1 503 Service Unavailable
content-type: text/plain
retry-after: 1
Connection: keep-alive
Keep-Alive: timeout=5
Transfer-Encoding: chunked

bosaltildi
```

Üç ayrıntı bilinçli seçimdir. Durum kodu **503**'tür, 500 değil: 500 sunucunun hatalı
olduğunu, 503 ise geçici olarak hizmet veremediğini söyler. İkisi arasındaki fark
istemcinin davranışını belirler — 500 alan istemci yeniden denememelidir, 503 alan
denemelidir. `Retry-After` başlığı bu denemenin ne zaman yapılacağını saniye cinsinden
bildirir; istemcinin tahmin yürütmesi gerekmez. Ve gövde kısadır: doygun bir sunucunun
uzun bir hata gövdesi üretmesi, kaçınmaya çalıştığı işin kendisidir.

Bağlantı başlıkları çalışma zamanının varsayılan ayarına bağlıdır.

## Neyi Boşaltmalı

Buraya kadar reddedilecek istek, eşiği aşan istekti. Bu en yalın politikadır ve bir
kusuru vardır: tüm işleri eşit görür. Oysa kütüphane servisinde bir ödünç iade işlemi ile
aylık rapor talebi eşit değildir.

İki ölçüt bu ayrımı verir. **Önem sırası** ile boşaltmada her işe bir sınıf verilir ve
doygunlukta önce düşük sınıf reddedilir; kritik sınıfa ayrılmış bir eşzamanlılık payı
her zaman boş tutulur. **Son tarihe göre** boşaltmada ise her iş bir gecikme bütçesiyle
gelir; kuyrukta beklerken bütçesi dolan iş, sırası geldiğinde işlenmeden atılır. İkincisi
özellikle değerlidir, çünkü kuyruğun başındaki işin çoktan anlamsızlaştığı durumu
yakalar — istemci çekilmiş olabilir.

Her iki politikada da boşaltma kararı sabit bir eşikten değil, **ölçülen bir
göstergeden** beslenmelidir: kuyrukta geçirilen süre, işçilerin doluluğu, dış bağımlılığın
gecikmesi. Sabit eşik, yükün biçimi değiştiğinde ya erken ya geç boşaltır.

## Yeniden Deneme Fırtınası

Boşaltmanın kendisi yeni bir tehlike üretir. Aynı anda reddedilen altı istemci, `Retry-After`
süresi dolduğunda aynı anda geri döner. Bu, sunucuyu doygun tutan bir döngüye yol açar
ve ona **yeniden deneme fırtınası** (retry storm) denir.

Panzehiri bu kursta zaten kuruldu: mesajlaşma konusunda tanıtılan üstel geri çekilme ve
sarsıntı. `Retry-After` değeri bir taban süredir; istemci bu tabana rastgele bir sarsıntı
ekler ve her başarısız denemede süreyi büyütür. Ayrıca istemci tarafında bir üst deneme
sınırı bulunmalıdır, yoksa reddedilen iş sonsuza dek geri gelir.

Sunucu tarafında da bir önlem vardır: reddedilen isteğin kütüğe yazılması, kabul edilenden
**daha ucuz** olmalıdır. Doygunlukta her reddi ayrıntılı kütüklemek, boşaltmanın kazandırdığı
kapasiteyi kütükleme işine harcar.

## Özet

- Yük boşaltma, kapasiteyi aşan işi kabul etmeyip geri çevirmektir; kararı veren kabul denetimi iş başlamadan önce çalışır.
- Eşik saniyedeki istek sayısına değil eşzamanlılığa konur; $L = \lambda W$ gereği sistemdeki iş sayısını sabitlemek gecikmeyi sabitler.
- Ölçüm, denetimsiz sunucuda gecikmenin 3 dilimden 15 dilime doğru yayıldığını, denetimli sunucuda ise kabul edilenlerin 3–6 dilimde kaldığını ve fazlanın sıfırıncı dilimde reddedildiğini gösterdi.
- Kabul denetimi belirsiz bir gecikmeyi kesin bir redde çevirir; 503 ile `Retry-After` istemciye ne yapacağını söyler, 500 ise yeniden denenmemesi gereken bir hatayı bildirir.
- Boşaltma yeniden deneme fırtınası doğurur; panzehiri istemci tarafında üstel geri çekilme ile sarsıntı, sunucu tarafında ise reddin ucuz tutulmasıdır.

## Sonraki Adım

Buraya kadar kurulan her şey işin **sunucu tarafındaki** dayanıklılığıyla ilgiliydi: iş
bir işçiye düşer, zamanında tetiklenir, ilerlemesi kaydedilir, kuyruk taşmaz, aşırı yükte
denetimli olarak reddedilir. Bu zincirin bir ucu hâlâ açık. İşi başlatan istemci, işin
kabul edildiğini öğrendi ama sonucun **ne zaman hazır olduğunu** bilmiyor. Uzun süren
raporun ilerleme yüzdesi, rezervasyon sırasındaki konumun değişmesi, şube stok sayacının
güncellenmesi — bunların hepsi sunucu tarafında hazır, istemci tarafında görünmez.
Sonraki konu bu bilginin istemciye nasıl ulaştığını ele alır ve en yalın yoldan, yani
istemcinin tekrar tekrar sormasından başlar.
