---
title: 'Katman 4 Dengeleme'
source: 'https://academia.sh/tr/kurslar/trafik-katmani/katman-4-dengeleme'
course: 'Trafik Katmanı'
language: tr
updated: '2026-08-17T18:11:03+00:00'
license: 'CC BY-SA 4.0'
---

# Katman 4 Dengeleme

Kararın bağlantı kurulurken bir kez verilmesi ve bunun bedeli: aynı toplam yükün eşit ve eşitsiz istemci paylarıyla ölçülmesi, kusursuz bağlantı dağıtımının dört kat istek sapması üretmesi, kararı vermek için okunan bilginin sayılması ve ölçülen dengesizliğin giriş kursundaki tepe hızda kaç kopyaya karşılık geldiğinin hesaplanması.

Önceki dersin dengeleyicisi kararını her istek için verdi ve kararı verebilmek için isteğin
yolunu okudu. Okumak bir seçimdir, zorunluluk değildir. 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 düzeyin adı **katman 4 dengeleme**dir. Katman modeli Ağ Modelleri ve Protokoller kursunda
kuruldu: katman 4 taşıma katmanıdır ve orada görülen şey adres, bağlantı noktası ve bayt
akışıdır; yol, başlık ve gövde bir katman yukarıdadır. Bu ders o düzeyi kurar, ne bilemediğini
sayar ve bilmemenin dağıtıma ne yaptığını ölçer.

## Bağlantı Başına Bir Karar

Katman 4 dengeleyici bir bağlantı kabul eder, bir kopya seçer, o kopyaya kendi bağlantısını açar
ve iki yön arasında baytları oldukça aktarır. Seçim bir kez yapılır; bağlantı kapanana kadar
geçerlidir.

```js
// k4/dengeleyici.mjs — katman 4 dengeleyici: karar baglanti kurulurken bir kez verilir, sonra
// iki yon oldugu gibi aktarilir. Kullanim: node k4/dengeleyici.mjs <nokta> <sayac.json> <kopyalar...>
import { createServer, connect } from "node:net";
import { writeFileSync } from "node:fs";

const nokta = Number(process.argv[2]);
const sayacYolu = process.argv[3];
const kopya = process.argv.slice(4).map(Number);
const sayac = { karar: 0, baglanti: Object.fromEntries(kopya.map((p) => [p, 0])), bayt: 0 };
let sira = 0;

if (Number.isInteger(nokta) === false || kopya.length === 0) {
  console.log("kullanim: node k4/dengeleyici.mjs <nokta> <sayac.json> <kopyalar...>");
} else {
  const s = createServer((disi) => {
    const hedef = kopya[sira++ % kopya.length];   // tek karar: bu baglanti hangi kopyaya ait
    sayac.karar += 1;
    sayac.baglanti[hedef] += 1;
    const ici = connect(hedef, "127.0.0.1");
    disi.on("data", (p) => { sayac.bayt += p.length; });   // gecen bayt sayilir, icerigi okunmaz
    disi.pipe(ici);
    ici.pipe(disi);
    for (const [a, b] of [[disi, ici], [ici, disi]]) {
      a.on("error", () => b.destroy());
      a.on("close", () => b.destroy());
    }
  });
  s.listen(nokta, "127.0.0.1");
  process.on("SIGTERM", () => { writeFileSync(sayacYolu, JSON.stringify(sayac)); process.exit(0); });
}
```

Kodun taşıdığı ayrım `node:net` ile `node:http` arasındaki ayrımdır. Bu dosyada bir HTTP isteği
nesnesi yoktur, dolayısıyla bir yol, bir başlık ya da bir takip numarası da yoktur. Sayaçta
tutulabilen tek içerik ölçüsü **geçen bayt** sayısıdır — ve o bile ne olduğu bilinmeyen baytların
sayısıdır.

Kopyalar bir katman yukarıda çalışır ve gördükleri isteği yola göre sayar. Sayaçlarını `/sayac`
yolundan bildirirler; bu yol dengeleyiciden değil doğrudan sorulur, bu yüzden ölçüme karışmaz.

```js
// k4/kopya.mjs — uygulama kopyasi: gordugu istekleri yola gore sayar, /sayac ile bildirir
import { createServer } from "node:http";

const [port, ad] = [Number(process.argv[2]), process.argv[3]];
const sayac = { ad, istek: 0, yol: {} };

if (Number.isInteger(port) === false) console.log("kullanim: node k4/kopya.mjs <nokta> <ad>");
else createServer((istek, yanit) => {
  yanit.sendDate = false;
  const yol = new URL(istek.url, "http://yerel").pathname;
  if (yol === "/sayac") {
    yanit.writeHead(200, { "content-type": "application/json" }).end(JSON.stringify(sayac));
    return;
  }
  sayac.istek += 1;
  sayac.yol[yol] = (sayac.yol[yol] ?? 0) + 1;
  yanit.writeHead(200, { "content-type": "application/json", "x-kopya": ad });
  yanit.end(JSON.stringify({ durum: "aktarma merkezinde", bolge: "35", adim: 4 }));
}).listen(port, "127.0.0.1");
```

İstemci düzeneğin asıl parametresini taşır: her istemci **tek bir kalıcı bağlantı** açar ve
payındaki istekleri o bağlantıdan gönderir. Payların eşit olup olmaması ölçümün girdisidir.
İstemciler sırayla koşar; böylece bağlantı kurulma sırası, dolayısıyla sıralı dağıtımın verdiği
eşleme belirlenimli olur.

```js
// k4/istemci.mjs — her istemci tek kalici baglanti acar ve payindaki istekleri sirayla gonderir
import { Agent, request } from "node:http";

const nokta = Number(process.argv[2]);
const PAY = (process.argv[3] ?? "1").split(",").map(Number);   // istemci basina istek sayisi

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

if (Number.isInteger(nokta) === false) console.log("kullanim: node k4/istemci.mjs <nokta> <pay,pay,...>");
else {
  let toplam = 0;
  for (let i = 0; i < PAY.length; i += 1) {            // istemciler sirayla kosar: baglanti sirasi belirlenimli
    const agent = new Agent({ keepAlive: true, maxSockets: 1 });
    for (let j = 0; j < PAY[i]; j += 1) {
      await bir(agent, `I${i}-${j}`, j % 2 === 0 ? "/takip" : "/olay");
      toplam += 1;
    }
    agent.destroy();
  }
  console.log(`${PAY.length} istemci, ${toplam} istek gonderildi (pay: ${PAY.join(",")})`);
}
```

Rapor betiği iki kaynağı birleştirir: dengeleyicinin bağlantı sayaçları ile kopyaların istek
sayaçları.

```js
// k4/rapor.mjs — dengeleyicinin sayac dosyasi ile kopyalarin /sayac ciktisini tek tabloda birlestirir
import { existsSync, readFileSync } from "node:fs";

const [sayacYolu, ...noktalar] = process.argv.slice(2);
if (sayacYolu === undefined || existsSync(sayacYolu) === false) {
  console.log("kullanim: node k4/rapor.mjs <sayac.json> <kopya-noktalari...>");
  process.exit(0);
}
const d = JSON.parse(readFileSync(sayacYolu, "utf8"));

const satir = [];
for (const p of noktalar) {
  const y = await fetch(`http://127.0.0.1:${p}/sayac`).then((r) => r.json());
  satir.push({ ad: y.ad, nokta: p, baglanti: d.baglanti[p], istek: y.istek,
    yol: Object.entries(y.yol).sort().map(([a, n]) => `${a.slice(1)}=${n}`).join(" ") });
}

const istek = satir.map((s) => s.istek);
console.log("kopya  baglanti  istek  yol dagilimi");
for (const s of satir) {
  console.log(`${s.ad.padEnd(5)}  ${String(s.baglanti).padStart(8)}  ${String(s.istek).padStart(5)}  ${s.yol}`);
}
console.log(`karar sayisi = ${d.karar} (baglanti basina 1), istek basina karar = ` +
  `${(d.karar / istek.reduce((a, b) => a + b, 0)).toFixed(3)}`);
console.log(`baglanti sapmasi = ${(Math.max(...satir.map((s) => s.baglanti)) / Math.min(...satir.map((s) => s.baglanti))).toFixed(2)}, ` +
  `istek sapmasi = ${(Math.max(...istek) / Math.min(...istek)).toFixed(2)}`);
console.log(`dengeleyiciden gecen istek bayti = ${d.bayt}`);
```

Düzenek iki kez koşar. İkisinde de altı istemci ve üç kopya vardır; değişen tek şey isteklerin
istemcilere nasıl dağıldığıdır. Bağlantı noktaları ortama bağlıdır.

```bash
# olc.sh — ayni toplam yuk iki istemci karisimiyla: esit paylar ve esitsiz paylar
for karisim in "10,10,10,10,10,10" "1,2,4,8,16,32"; do
  node k4/kopya.mjs 8871 k1 & K1=$!
  node k4/kopya.mjs 8872 k2 & K2=$!
  node k4/kopya.mjs 8873 k3 & K3=$!
  node k4/dengeleyici.mjs 8841 sayac.json 8871 8872 8873 & D=$!
  sleep 1
  node k4/istemci.mjs 8841 "$karisim"
  kill -TERM $D; sleep 0.3
  node k4/rapor.mjs sayac.json 8871 8872 8873
  kill $K1 $K2 $K3; sleep 0.3
  echo
done
```

```
6 istemci, 60 istek gonderildi (pay: 10,10,10,10,10,10)
kopya  baglanti  istek  yol dagilimi
k1            2     20  olay=10 takip=10
k2            2     20  olay=10 takip=10
k3            2     20  olay=10 takip=10
karar sayisi = 6 (baglanti basina 1), istek basina karar = 0.100
baglanti sapmasi = 1.00, istek sapmasi = 1.00
dengeleyiciden gecen istek bayti = 4590

6 istemci, 63 istek gonderildi (pay: 1,2,4,8,16,32)
kopya  baglanti  istek  yol dagilimi
k1            2      9  olay=4 takip=5
k2            2     18  olay=9 takip=9
k3            2     36  olay=18 takip=18
karar sayisi = 6 (baglanti basina 1), istek basina karar = 0.095
baglanti sapmasi = 1.00, istek sapmasi = 4.00
dengeleyiciden gecen istek bayti = 4848
```

## İki Sapma Aynı Tabloda

Bu sayılar **ölçüm** sınıfındadır ve belirlenimlidir; istemciler sırayla koştuğu ve dağıtım
kuralı sıralı olduğu için başka bir makinede de aynı bölünme çıkar.

İki koşumda da bağlantı sapması 1,00'dır: dengeleyici altı bağlantıyı üç kopyaya ikişer ikişer
paylaştırdı ve bu paylaşımda hiçbir kusur yok. Kendisine verilen işi kusursuz yapıyor. Birinci
koşumda istek sapması da 1,00: paylar eşit olduğu için bağlantı dengesi istek dengesine
çeviriyor.

İkinci koşumda aynı kusursuz bağlantı dağıtımı **4,00 kat** istek sapması üretiyor. Kopyalar 9,
18 ve 36 istek gördü; en yüklü kopya en az yüklü olanın dört katını taşıdı. Değişen tek şey
isteklerin bağlantılara nasıl dağıldığıdır. **Katman 4 dengeleyici bağlantıları dengeler, isteği
dengelemez;** ikisi aynı şey olmadığı için ölçüm iki ayrı sapma sütunu gerektirir.

Sapmanın kaynağı kalıcı bağlantıdır. Bir bağlantı bir istek taşıyorsa iki sayı aynıdır; bir
bağlantı otuz iki istek taşıyorsa dengeleyicinin bir kararı otuz iki isteği birden bağlar. Karar
bir kez verildiği için de düzeltilemez: dengeleyici 36 isteğin aynı kopyaya gittiğini fark
etmez, çünkü onları hiç saymaz.

## Ne Bilinmiyor

Karar sütunu bilmemenin ölçüsüdür: 63 istek için 6 karar, istek başına 0,095 karar. Katman 4
dengeleyicinin işi bu orandan ucuzdur — bir bağlantı için bir kez seçim yapıp sonra baytları
geçirmek, her isteği ayrıştırıp yeniden yazmaktan daha az iştir.

Ödenen bedel yol dağılımı sütununda görünüyor. Her kopya hem `takip` hem `olay` isteği aldı ve
oranlar bağlantı paylarının aynısı. Kopyaların bir kısmını okumaya, bir kısmını yazmaya
ayırmak bu düzeyde **olanaksızdır**: karar bağlantı kurulurken verilir ve o anda henüz bir yol
gönderilmemiştir. Aynı kısıt daha ince ayrımlar için de geçerlidir — takip numarasına, istemci
türüne ya da bir başlığa bakan bir kural yazılamaz, çünkü bunların hiçbiri katman 4'te
görünmez. Dengeleyicinin gördüğü 4848 bayt, içeriği bilinmeyen bir akıştır.

Bilinmemenin bir de olumlu yüzü var. Katman 4 dengeleyici HTTP bilmediği için HTTP'ye bağlı
değildir: aynı kod başka bir bağlantı tabanlı protokol için de çalışır ve gövdeyi
tamponlamadığı için akış hâlinde giden veri araya girmeden geçer.

## Hesaba Geri Dönüş

Önceki ders 513,89 istek/s tepe hızı üç kopyaya bölmüş ve kopya başına 171,30 istek/s bulmuştu.
O bölme, dağıtımın kusursuz olduğunu varsayıyordu. Ölçülen sapma varsayımı bozar. Aşağıdaki
hesap ölçülen paylardan bir **dengesizlik çarpanı** çıkarır: en yüklü kopyanın payı ile kopya
sayısının çarpımı, kusursuz dengede 1'dir.

Bir varsayım daha gerekir. **Y4 — kalıcı bağlantı başına ortalama istek: 10.** Gerekçe: bir
kullanıcı takip sayfasını açtığında aynı bağlantıdan birkaç sorgu geçer; sayı bu konunun kendi
varsayımıdır, K01'in tablosuna eklenmez.

```js
// k4/kapasite.mjs — olculen dengesizligin K01 tepe hizindaki karsiligi ve gereken kopya sayisi
const TEPE_UC = 513.89;            // K01 Kabaca Buyukluk Hesabi: tepe ucta istek/s
const GUVENLI = 200;              // 01. ders: Y1 x Y2 = 400 x 0.50
const ISTEK_BAGLANTI = 10;        // varsayim Y4: kalici baglanti basina ortalama istek

const OLCUM = { esit: [20, 20, 20], esitsiz: [9, 18, 36] };   // 02. dersin olcumu

const dengesizlik = (d) => (Math.max(...d) / d.reduce((a, b) => a + b, 0)) * d.length;
const gereken = (d) => Math.ceil((dengesizlik(d) * TEPE_UC) / GUVENLI);

console.log("karisim   paylar        en yuklu pay   dengesizlik   en yuklu kopya istek/s   doluluk   gereken kopya");
for (const [ad, d] of Object.entries(OLCUM)) {
  const enYuklu = Math.max(...d) / d.reduce((a, b) => a + b, 0);
  const hiz = enYuklu * TEPE_UC;
  console.log(`${ad.padEnd(9)} ${d.join("/").padEnd(13)} ${enYuklu.toFixed(4).padStart(12)} ` +
    `${dengesizlik(d).toFixed(3).padStart(13)} ${hiz.toFixed(2).padStart(24)} ` +
    `${(hiz / 400).toFixed(3).padStart(9)} ${String(gereken(d)).padStart(15)}`);
}

console.log(`\nkusursuz dengede kopya = ${gereken(OLCUM.esit)}, olculen dengesizlikte = ` +
  `${gereken(OLCUM.esitsiz)}: fark ${gereken(OLCUM.esitsiz) - gereken(OLCUM.esit)} kopya, ` +
  `yalnizca dagilim sapmasi icin`);

console.log(`\nkarar hizi (baglanti basina 1 karar, Y4 = ${ISTEK_BAGLANTI}): ` +
  `${(TEPE_UC / ISTEK_BAGLANTI).toFixed(2)} karar/s`);
console.log(`istek basina karar verilse: ${TEPE_UC} karar/s, ${ISTEK_BAGLANTI} kat`);
console.log(`duyarlilik: Y4 = 1 ise iki hiz esitlenir, Y4 = 100 ise oran 100 kat olur`);
```

```
karisim   paylar        en yuklu pay   dengesizlik   en yuklu kopya istek/s   doluluk   gereken kopya
esit      20/20/20            0.3333         1.000                   171.30     0.428               3
esitsiz   9/18/36             0.5714         1.714                   293.65     0.734               5

kusursuz dengede kopya = 3, olculen dengesizlikte = 5: fark 2 kopya, yalnizca dagilim sapmasi icin

karar hizi (baglanti basina 1 karar, Y4 = 10): 51.39 karar/s
istek basina karar verilse: 513.89 karar/s, 10 kat
duyarlilik: Y4 = 1 ise iki hiz esitlenir, Y4 = 100 ise oran 100 kat olur
```

Hesap sınıfındaki bu sayılar önceki dersin sonucunu düzeltiyor. Kusursuz dengede en yüklü kopya
171,30 istek/s ve 0,428 doluluk taşır; ölçülen dengesizlikte 293,65 istek/s ve 0,734 doluluk
taşır. İkinci sayı Y2 ile konan 0,50 hedefinin üstündedir, yani üç kopyalı tasarım tepe yükte
hedefi tutmaz. Hedefi tutmak için gereken kopya sayısı 3 yerine **5**'tir ve fazladan iki kopya
yükün büyümesi için değil, yalnızca dağılım sapması için ödenir.

Karar hızı satırı bir sonraki dersin fiyat etiketini de veriyor. Bağlantı başına karar
verildiğinde dengeleyici saniyede 51,39 karar üretir; istek başına karar verilse 513,89 karar
üretir, on kat fazla. Sapmayı düzeltmenin yolu bu on katı ödemekten geçiyor.

## Özet

- Katman 4 dengeleme kararı bağlantı kurulurken bir kez verir; o bağlantıdan akan bütün istekler
  aynı kopyaya gider ve karar sonradan düzeltilmez.
- Aynı toplam yük eşit paylarla 20–20–20, eşitsiz paylarla 9–18–36 bölündü: bağlantı sapması iki
  koşumda da 1,00, istek sapması 1,00'a karşı 4,00.
- Bağlantıyı dengelemek isteği dengelemek değildir; sapmanın kaynağı kalıcı bağlantıların eşit
  sayıda istek taşımamasıdır ve dengeleyici bunu ölçemez, çünkü istekleri saymaz.
- Karar sayısı 63 istek için 6'dır (istek başına 0,095); bu ucuzluk yol, başlık ve takip
  numarasının görünmemesiyle satın alınır — okuma ile yazmayı ayrı kopyalara ayırmak bu düzeyde
  olanaksızdır.
- Ölçülen dengesizlik çarpanı 1,714 tepe hızda en yüklü kopyayı 293,65 istek/s ve 0,734 dolulukla
  hedefin üstüne çıkarıyor; hedefi tutmak 3 yerine 5 kopya gerektiriyor.
- İstek başına karar vermenin bedeli Y4 = 10 varsayımıyla 51,39 karar/s yerine 513,89 karar/s,
  yani on kattır.

## Sonraki Adım

Ölçülen 4,00 kat sapma ve ayrılamayan iki akış aynı nedenden geliyor: karar, karar için gereken
bilgi ortaya çıkmadan önce veriliyor. Bilgi bir katman yukarıda vardır — yol, başlık, yöntem ve
sorgu dizgisi bağlantı kurulduktan hemen sonra akmaya başlar. Bir dengeleyici bunları okumayı
seçerse her istek için yeniden karar verebilir, isteği içeriğine göre başka bir kopya kümesine
gönderebilir ve on kat karar üretmenin faturasını öder. Sonraki ders bu düzeyi kurar: aynı
istemci karışımının içerik farkındalıklı bir dengeleyiciden geçirilmesiyle sapmanın ne olduğunu,
okuma ile yazmanın ayrı havuzlara bölünmesinin kopya sayısını nasıl değiştirdiğini ve
dengeleyicinin isteği ayrıştırmasının hangi yeni sorumlulukları getirdiğini ölçer.
