---
title: 'Yük Dengeleyici Rolü'
source: 'https://academia.sh/tr/kurslar/trafik-katmani/yuk-dengeleyici-rolu'
course: 'Trafik Katmanı'
language: tr
updated: '2026-08-17T18:11:03+00:00'
license: 'CC BY-SA 4.0'
---

# Yük Dengeleyici Rolü

Aynı işi yapan kopyalar arasında isteği paylaştıran katmanın üç sorumluluğu: dağıtımın yerel süreçlerle ölçülmesi, bir kopya düştüğünde sağlık denetimi olan ve olmayan düzeneklerin yanıtlanan istek oranıyla karşılaştırılması, TLS sonlandırmanın konum kararı olarak ele alınması ve giriş kursunda hesaplanan tepe istek hızının kopya sayısına bölünmesi.

Önceki konu isteklerin bir kısmını uygulamaya **hiç ulaştırmamayı** başardı: kenar önbelleği takip
yanıtlarının onda dokuzunu sınırda karşıladı, ayrılan içerik yolu bir sayfa yüklemesinin isteklerinin
neredeyse tamamını uygulamadan uzaklaştırdı ve alan adı katmanı isteğin hangi bölgeye gideceğini
seçti. Geriye uygulamaya gerçekten ulaşması gereken istekler kaldı — uçta saniyede 513,89 tanesi.
Bunlar için bir soru yanıtsızdır: bölge seçildikten sonra, aynı işi yapan birden çok kopya varken
istek **hangisine** düşer, ve o kopya ayakta değilse bunu kim fark eder.

Bu ders o iki soruyu tek bir bileşene bağlar. **Yük dengeleyici** (load balancer), aynı işi yapan
kopyaların önünde durup gelen isteği içlerinden birine yönlendiren aygıttır. Dersin işi bu
aygıtın sorumluluklarını saymak, her birinin kod düzeyinde ölçülebilen sonucunu almak ve Sistem
Tasarımına Giriş kursunda hesaplanan tepe istek hızının kopya sayısına bölünmesinin ne verdiğini
göstermektir.

## Üç Sorumluluk

Dengeleyicinin taşıdığı işler ayrı ayrı adlandırılabilir ve her biri ayrı bir karar gerektirir.

**Dağıtım.** Gelen isteğin hangi kopyaya gideceğinin seçilmesi. Seçimin kuralı bir sonraki
derslerin konusudur; bu derste kural en yalın biçimiyle **sıralı** dağıtımdır — kopyalar sırayla
seçilir.

**Sağlık denetimi.** Bir kopyanın hâlâ istek alabilir durumda olup olmadığının bağımsız olarak
sınanması ve olmayanın havuzdan çıkarılması. Denetim isteği kullanıcının isteğinden ayrıdır:
dengeleyici belirli aralıklarla kopyalara sorar, yanıt alamadığında o kopyayı dağıtımdan düşürür.

**TLS sonlandırma.** Şifreli bağlantının nerede biteceğinin seçilmesi. Bağlantı dengeleyicide
biterse dengeleyici isteğin içeriğini görür; kopyaya kadar şifreli taşınırsa görmez.

Bu üç işin bir kısmını Sunucu Tarafı Temelleri kursunda kurulan **ters vekil** de yapar; ikisinin
işlev örtüşmesi ve ayrımı bu konunun beşinci dersinin konusudur. Burada dengeleyici tek bir rolle
ele alınır: aynı işi yapan kopyalar arasında paylaştırma.

## Düzenek

Ölçüm yerel süreçlerle kurulur. Üç kopya birer `node:http` sunucusudur ve her biri yanıtına
kendi adını yazar; dengeleyici sıralı dağıtım yapar ve sağlık denetimi açık ya da kapalı
çalışabilir. Gerçek bir yük dengeleyici, bulut ortamı ya da kapsayıcı kurulmaz.

```js
// denge/kopya.mjs — bir uygulama kopyasi: takip yanitini dondurur, kendi adini basliga yazar
import { createServer } from "node:http";

const [port, ad] = [Number(process.argv[2]), process.argv[3]];

const GOVDE = (no) => JSON.stringify({
  no, durum: "aktarma merkezinde", bolge: "35", adim: 4,
  rota: ["kabul", "cikis", "aktarma-34"],
});

if (Number.isInteger(port) === false) console.log("kullanim: node denge/kopya.mjs <nokta> <ad>");
else createServer((istek, yanit) => {
  const url = new URL(istek.url, "http://yerel");
  if (url.pathname === "/saglik") { yanit.writeHead(200, { "x-kopya": ad }).end("ayakta"); return; }
  const govde = GOVDE(url.searchParams.get("no") ?? "-");
  yanit.writeHead(200, { "content-type": "application/json", "x-kopya": ad });
  yanit.end(govde);
}).listen(port, "127.0.0.1");
```

Dengeleyici üç işten ikisini yapıyor: sıraya göre bir kopya seçiyor ve kopyaların sağlığını ayrı
bir zamanlayıcıda denetliyor. Denetim aralığı 200 milisaniye, düşmüş sayılma eşiği tek bir
başarısız turdur; ikisi de bu konunun varsayımıdır ve aşağıda Y3 olarak anılır.

```js
// denge/dengeleyici.mjs — sirali dagitim + saglik denetimi. Kullanim:
//   node denge/dengeleyici.mjs <nokta> <acik|kapali> <kopya-noktalari...>
import { createServer, request, get } from "node:http";

const ARALIK = 200;                  // varsayim Y3: saglik denetimi araligi (ms)
const ESIK = 1;                      // varsayim Y3: ust uste kac basarisizlik dusmus sayilir

const nokta = Number(process.argv[2]);
const saglikAcik = process.argv[3] === "acik";
const kopya = process.argv.slice(4).map((p) => ({ nokta: Number(p), ayakta: true, hata: 0 }));

let sira = 0, dusen = 0;

function denetle(k) {
  const r = get({ port: k.nokta, path: "/saglik", timeout: 100 }, (y) => {
    y.resume();
    if (y.statusCode === 200) { k.hata = 0; k.ayakta = true; } else basarisiz(k);
  });
  r.on("error", () => basarisiz(k));
  r.on("timeout", () => r.destroy());
}
function basarisiz(k) { k.hata += 1; if (k.hata >= ESIK) k.ayakta = false; }

if (Number.isInteger(nokta) === false || kopya.length === 0) {
  console.log("kullanim: node denge/dengeleyici.mjs <nokta> <acik|kapali> <kopya-noktalari...>");
} else {
  if (saglikAcik) setInterval(() => kopya.forEach(denetle), ARALIK).unref();
  createServer((istekDisi, yanitDisi) => {
    if (istekDisi.url === "/yonet/durum") {
      yanitDisi.writeHead(200, { "content-type": "application/json" });
      yanitDisi.end(JSON.stringify({ ulasilamayan: dusen,
        ayakta: kopya.filter((k) => k.ayakta).map((k) => k.nokta) }));
      return;
    }
    const havuz = kopya.filter((k) => k.ayakta);
    if (havuz.length === 0) { yanitDisi.writeHead(503).end("havuz bos"); return; }
    const secilen = havuz[sira++ % havuz.length];
    const istekIc = request({ port: secilen.nokta, path: istekDisi.url,
      method: istekDisi.method, headers: istekDisi.headers }, (yanitIc) => {
      yanitDisi.writeHead(yanitIc.statusCode, yanitIc.headers);
      yanitIc.pipe(yanitDisi);
    });
    istekIc.on("error", () => { dusen += 1; yanitDisi.writeHead(502).end("kopyaya ulasilamadi"); });
    istekDisi.pipe(istekIc);
  }).listen(nokta, "127.0.0.1");
}
```

İstemci istekleri **sırayla** gönderir; eşzamanlılık 1'de tutulması dağıtım sayılarını
belirlenimli kılar, yoksa aynı düzenek her koşumda başka bir bölünme verir.

```js
// denge/istemci.mjs — sirayla istek gonderir, yaniti hangi kopyanin verdigini sayar
import { Agent, request } from "node:http";

const [nokta, adet, etiket] = [Number(process.argv[2]), Number(process.argv[3]), process.argv[4]];
const agent = new Agent({ keepAlive: true, maxSockets: 1 });

function bir(no) {
  return new Promise((coz, sap) => {
    const r = request({ port: nokta, path: `/takip?no=${no}`, agent }, (y) => {
      y.resume();
      y.on("end", () => coz({ kod: y.statusCode, kopya: y.headers["x-kopya"] ?? "-" }));
    });
    r.on("error", sap);
    r.end();
  });
}

if (Number.isInteger(nokta) === false) console.log("kullanim: node denge/istemci.mjs <nokta> <adet> <etiket>");
else {
  const sayac = new Map();
  let basarili = 0, basarisiz = 0;
  for (let i = 0; i < adet; i += 1) {
    const s = await bir(`G${i}`);
    if (s.kod === 200) basarili += 1; else basarisiz += 1;
    const anahtar = s.kod === 200 ? s.kopya : `kod ${s.kod}`;
    sayac.set(anahtar, (sayac.get(anahtar) ?? 0) + 1);
  }
  const dagitim = [...sayac].sort().map(([a, n]) => `${a}=${n}`).join("  ");
  console.log(`${etiket.padEnd(30)} yanitlanan ${String(basarili).padStart(4)}/${adet}` +
    `  basarisiz ${String(basarisiz).padStart(3)}  |  ${dagitim}`);
  agent.destroy();
}
```

Sürücü betik aynı üç kopyanın önüne iki dengeleyici koyar: birinde sağlık denetimi açık,
ötekinde kapalı. Sonra `k2` kopyası öldürülür ve aynı yük her iki dengeleyiciye gönderilir.
Bağlantı noktası numaraları ortama bağlıdır; makinede kullanımdaysa değiştirilmelidir.

```bash
# olc.sh — uc kopya, iki dengeleyici (saglik denetimi acik ve kapali); k2 kopyasi dusurulur
node denge/kopya.mjs 8861 k1 & K1=$!
node denge/kopya.mjs 8862 k2 & K2=$!
node denge/kopya.mjs 8863 k3 & K3=$!
node denge/dengeleyici.mjs 8851 acik   8861 8862 8863 & DA=$!
node denge/dengeleyici.mjs 8852 kapali 8861 8862 8863 & DK=$!
sleep 1

node denge/istemci.mjs 8851 300 "uc kopya ayakta"
kill $K2; sleep 1
node denge/istemci.mjs 8851 300 "k2 dustu, denetim acik"
node denge/istemci.mjs 8852 300 "k2 dustu, denetim kapali"
echo "havuz (denetim acik)  : $(curl -s localhost:8851/yonet/durum)"
echo "havuz (denetim kapali): $(curl -s localhost:8852/yonet/durum)"
kill $K1 $K3 $DA $DK
```

```
uc kopya ayakta                yanitlanan  300/300  basarisiz   0  |  k1=100  k2=100  k3=100
k2 dustu, denetim acik         yanitlanan  300/300  basarisiz   0  |  k1=150  k3=150
k2 dustu, denetim kapali       yanitlanan  200/300  basarisiz 100  |  k1=100  k3=100  kod 502=100
havuz (denetim acik)  : {"ulasilamayan":0,"ayakta":[8861,8863]}
havuz (denetim kapali): {"ulasilamayan":100,"ayakta":[8861,8862,8863]}
```

## Ölçülen Etki

Bu sayılar **ölçüm** sınıfındadır: yerel süreçlerden alınmıştır. Belirlenimlidir, çünkü istekler
sırayla gönderilir ve dağıtım kuralı sıralıdır; başka bir makinede de aynı bölünme çıkar, ama
bağlantı noktaları ortama bağlıdır.

İlk satır dağıtımı gösteriyor: üç kopya ayaktayken 300 istek 100–100–100 bölünüyor. Dengeleyici
tek başına bir kazanç üretmiyor, yalnız yükü üçe ayırıyor — ve bu ayırma bir sonraki bölümde bir
kapasite hesabına dönüşecek.

İkinci ve üçüncü satır dersin asıl ölçümüdür. Aynı arıza, aynı yük, aynı kopyalar. Sağlık
denetimi açık dengeleyici 300 isteğin 300'ünü yanıtladı ve yükü kalan iki kopyaya 150–150 böldü;
havuz durumu `k2` kopyasının bağlantı noktasını listeden düşürmüş durumda. Sağlık denetimi kapalı
dengeleyici 300 isteğin yalnız 200'ünü yanıtladı: sıralı dağıtım her üç istekten birini ölü
kopyaya gönderdi ve 100 istek 502 ile döndü. Havuz durumu üç kopyanın da ayakta sayıldığını
gösteriyor.

Buradan çıkan sonuç dengeleyicinin tanımını değiştirir. **Dağıtım tek başına hizmet
erişilebilirliği üretmez.** Kopya sayısını artırmak, düşen kopyayı fark eden bir denetim yoksa yalnızca arızayı
seyrelten bir şeydir: bir kopya düştüğünde sistem tamamen durmaz, ama isteklerin üçte biri
düşmeye devam eder ve bu durum kendini bir toplu kesinti olarak duyurmaz. Sağlık denetimi,
kopyalamayı bir hizmet erişilebilirliği aracına çeviren parçadır.

## TLS Sonlandırma Nerede Biter

Şifreli bağlantının nerede bittiği bir **konum kararıdır** ve bu kursta ölçülen sonucu bir
süre değil, bir görünürlüktür. Yukarıdaki dengeleyici `istekDisi.url` değerini okuyor —
`/yonet/durum` yolunu ayırt edebilmesi buna dayanıyor. Bu satırın var olabilmesinin koşulu
bağlantının dengeleyicide sonlanmasıdır: şifreli akış kopyaya kadar taşınıyorsa dengeleyicinin
elinde yol, başlık ve gövde değil yalnız baytlar olur. TLS ve el sıkışma Ağ Modelleri ve
Protokoller kursunda kuruldu ve burada yeniden anlatılmaz; kararın bu derse ait sonucu şudur:
**sonlandırma, içeriğe bakan bir dağıtım kuralının önkoşuludur.**

Kararın ikinci sonucu sayılabilir. Sertifikayı tutan uç sayısı, sonlandırma dengeleyicide
yapıldığında 1, kopyalarda yapıldığında kopya sayısı kadardır; havuza bir kopya eklemek ilkinde 0
sertifika işi, ikincisinde 1 sertifika işi doğurur. Şifreleme işinin işlemci maliyeti burada
ölçülmez, çünkü seçilen şifre takımına ve donanıma bağlıdır — bu kursun kuralı gereği
ölçülmeyen bir sayı yazılmaz.

## Hesaba Geri Dönüş

Sistem Tasarımına Giriş kursu uçta tepe istek hızını 513,89 istek/s olarak hesaplamıştı. O sayı
tek bir kopyanın taşıyacağı yük değildir; kopya sayısına bölünür. Bölmenin yapılabilmesi için bu
konunun kendi varsayımları gerekir ve bunlar K01'in V1–V13 tablosuna **eklenmez**:

**Y1 — kopya başına doyum verimi: 400 istek/s.** Gerekçe: K01'in Gecikme ve Verim dersinde çıplak
bir uçta ölçülen üst sınır 4268 istek/s'ydi; gerçek takip ucu depoya bakar, seri hâle getirir ve
yetkilendirme yapar, bu yüzden plan sayısı ölçülenin çok altında seçilir. **Y2 — hedef doluluk
0,50.** Gerekçe: aynı dersin kuyruk modelinde doluluk yüzde 50'de süreyi 1,4 katına, yüzde 90'da
7 katına çıkarıyordu. **Y3 — sağlık denetimi aralığı 200 ms, eşik 1 tur.** Gerekçe: düzenekte
kullanılan değerler.

```js
// denge/kapasite.mjs — K01 hesabinin kopya sayisina bolunmesi ve saglik denetiminin butceye etkisi
const TEPE_UC = 513.89;            // K01 Kabaca Buyukluk Hesabi: tepe ucta istek/s
const GUNLUK_ISTEK = 12_000_000 + 2_800_000;   // K01: gunluk takip sorgusu + durum olayi
const DOYUM = 400;                 // varsayim Y1: kopya basina doyum verimi (istek/s)
const HEDEF_DOLULUK = 0.5;         // varsayim Y2: kopyanin hedef dolulugu
const DENETIM_MS = 200;            // varsayim Y3: saglik denetimi araligi, esik 1 tur
const KURTARMA_DK = 10;            // K01 Erisilebilirligin Sayisal Ifadesi: kurtarma suresi
const ARIZA_AY = 2.82;             // K01: ayda butceye sigan ariza sayisi

const guvenli = DOYUM * HEDEF_DOLULUK;
const enAz = Math.ceil(TEPE_UC / guvenli);
console.log(`kopya basina guvenli hiz = ${guvenli} istek/s (${DOYUM} x ${HEDEF_DOLULUK})`);
console.log(`en az kopya = ceil(${TEPE_UC} / ${guvenli}) = ${enAz}\n`);

console.log("kopya  kopya basina istek/s  doluluk  bir kopya dususunde istek/s  o an doluluk");
for (const n of [enAz, enAz + 1, enAz + 2]) {
  const pay = TEPE_UC / n, kalan = TEPE_UC / (n - 1);
  console.log(`${String(n).padStart(5)}  ${pay.toFixed(2).padStart(20)}  ` +
    `${(pay / DOYUM).toFixed(3).padStart(7)}  ${kalan.toFixed(2).padStart(27)}  ` +
    `${(kalan / DOYUM).toFixed(3).padStart(12)}`);
}

const ortalama = GUNLUK_ISTEK / 86_400;
console.log(`\nortalama uc hizi = ${ortalama.toFixed(2)} istek/s; tepe / ${enAz} kopya = ` +
  `${(TEPE_UC / enAz).toFixed(2)} istek/s (tepe carpani ${enAz} oldugu icin ayni sayi)`);

const ayIstek = GUNLUK_ISTEK * 30;
console.log(`\npencere            dusen istek/ariza   aylik dusen istek   istek tabanli erisilebilirlik`);
for (const [ad, sn] of [["saglik denetimi", DENETIM_MS / 1000], ["elle kurtarma", KURTARMA_DK * 60]]) {
  const bir = (TEPE_UC / enAz) * sn, aylik = bir * ARIZA_AY;
  console.log(`${ad.padEnd(18)} ${bir.toFixed(2).padStart(17)} ${aylik.toFixed(0).padStart(19)}   ` +
    `%${(100 * (1 - aylik / ayIstek)).toFixed(5)}`);
}

const denetimHizi = (enAz * 1000) / DENETIM_MS;
console.log(`\ndenetim yuku = ${denetimHizi} istek/s, tepe ucun %${((denetimHizi / TEPE_UC) * 100).toFixed(1)}'i`);
console.log(`duyarlilik: Y1 iki katina cikarsa en az kopya = ${Math.ceil(TEPE_UC / (2 * DOYUM * HEDEF_DOLULUK))}, ` +
  `yarilanirsa = ${Math.ceil(TEPE_UC / (0.5 * DOYUM * HEDEF_DOLULUK))}`);
```

```
kopya basina guvenli hiz = 200 istek/s (400 x 0.5)
en az kopya = ceil(513.89 / 200) = 3

kopya  kopya basina istek/s  doluluk  bir kopya dususunde istek/s  o an doluluk
    3                171.30    0.428                       256.94         0.642
    4                128.47    0.321                       171.30         0.428
    5                102.78    0.257                       128.47         0.321

ortalama uc hizi = 171.30 istek/s; tepe / 3 kopya = 171.30 istek/s (tepe carpani 3 oldugu icin ayni sayi)

pencere            dusen istek/ariza   aylik dusen istek   istek tabanli erisilebilirlik
saglik denetimi                34.26                  97   %99.99998
elle kurtarma              102778.00              289834   %99.93472

denetim yuku = 15 istek/s, tepe ucun %2.9'i
duyarlilik: Y1 iki katina cikarsa en az kopya = 2, yarilanirsa = 6
```

Bu sayıların hepsi **hesap** sınıfındadır. En az kopya sayısı üçtür ve o üç kopyada her biri
171,30 istek/s taşır. İkinci tablonun ilk sütunu bir kopya düştüğü **anda** ne olduğunu
gösteriyor: kalan iki kopya 256,94 istek/s'ye ve 0,642 doluluğa çıkar; üç kopya seçilen bir
tasarım, tek bir arızada hedef doluluğunun üstüne taşar. Dört kopyada aynı durumda doluluk
0,428'de kalır — yani "en az kopya sayısı" ile "bir kopya düşse de hedefi tutan kopya sayısı"
ayrı iki sayıdır ve aradaki fark bir kopyadır.

Ortalama satırı bir çakışmayı kaydediyor: tepenin üç kopyaya bölümü 171,30 istek/s ve sistemin
ortalama uç hızı da 171,30 istek/s. İki sayı eşittir çünkü tepe çarpanı 3'tür ve kopya sayısı da
3 seçilmiştir; bu bir bağıntı değildir, varsayımların ürettiği bir çakışmadır. Kopya sayısı
değiştiğinde eşitlik bozulur.

Son tablo sağlık denetiminin kesinti bütçesindeki karşılığıdır. K01'in Erişilebilirliğin Sayısal
İfadesi dersi aylık 43,2 dakikalık bütçenin 28,2 dakikasını arızaya ayırmış, on dakikalık
kurtarma süresiyle ayda 2,82 arıza saymıştı. O hesap her arızanın **tam kesinti** olduğunu
varsayıyordu. Üç kopyalı bir havuzda tek bir kopyanın düşmesi tam kesinti değildir: sağlık
denetimi varsa arıza başına 34,26 istek düşer ve aylık toplam 97 istektir. Denetim yoksa aynı
arıza kurtarmaya kadar sürer, arıza başına 102 778 istek düşer ve aylık toplam 289 834'e çıkar —
aradaki oran 2989 kattır. Denetimin faturası da hesaplanmıştır: kopyalara giden 15 istek/s, tepe
uçtaki yükün yüzde 2,9'u.

İstek tabanlı sütun bir uyarı içeriyor. Denetimsiz düzenin oranı yüzde 99,93472'dir ve yüzde
99,9'luk hedefin üstünde görünür; oysa aynı arızalar zaman tabanlı bütçenin arıza payının
tamamını harcar. Aynı arıza iki tabanda iki farklı büyüklükte görünüyor, çünkü isteklerin
yalnızca üçte biri düşüyor. K01 bu iki tabanı ayırmıştı; buradaki sayılar ayrımın neden gerekli
olduğunu gösteriyor.

## Özet

- Yük dengeleyici üç sorumluluk taşır: dağıtım, sağlık denetimi ve TLS sonlandırma; ilki yükü
  paylaştırır, ikincisi düşen kopyayı havuzdan çıkarır, üçüncüsü şifreli bağlantının nerede
  bittiğini belirler.
- Aynı arızada sağlık denetimi açık düzenek 300/300 isteği yanıtladı ve yükü 150–150 böldü;
  kapalı düzenek 200/300 yanıtladı ve 100 istek 502 ile döndü.
- Dağıtım tek başına hizmet erişilebilirliği üretmez: düşen kopyayı fark eden bir denetim yoksa
  isteklerin üçte biri düşmeye devam eder ve bu bir toplu kesinti olarak görünmez.
- TLS sonlandırmanın bu dersteki ölçülen sonucu görünürlüktür: bağlantı dengeleyicide bitmezse
  yol ve başlık okunamaz, dolayısıyla içeriğe bakan bir dağıtım kuralı kurulamaz.
- Tepe 513,89 istek/s, kopya başına güvenli hız 200 istek/s (Y1 ve Y2) ile en az 3 kopya verir ve
  her kopya 171,30 istek/s taşır; bir kopya düştüğünde kalanlar 256,94 istek/s ve 0,642 dolulukla
  hedefin üstüne taşar, dört kopyada taşmaz.
- Sağlık denetimi arıza başına düşen isteği 102 778'den 34,26'ya indiriyor (aylık 289 834'e karşı
  97, oran 2989 kat); denetimin kendi yükü 15 istek/s, tepe uçtaki yükün yüzde 2,9'u.

## Sonraki Adım

Bu dersin dengeleyicisi kararını her istek için verdi ve kararı verebilmek için isteğin yolunu
okudu — `/yonet/durum` ayrımı buna dayanıyordu. Okumak bir seçimdir, zorunluluk değil. Bir
dengeleyici isteğin içine hiç bakmadan da çalışabilir: kararı bağlantı kurulurken bir kez verir,
sonra o bağlantıdan akan her şeyi aynı kopyaya geçirir. Bu daha az iş yapar ve daha az şey bilir.
Sonraki ders bu düzeyi kurar: bağlantı düzeyinde dağıtımın ne bilemediğini, kalıcı bağlantıların
dağıtımı nasıl bozduğunu ve bağlantı başına verilen bir kararın istek başına dağılımı hangi
sapmayla ürettiğini ölçer.
