---
title: 'Ağ Geçidi Yönlendirme ve Toplama'
source: 'https://academia.sh/tr/kurslar/trafik-katmani/ag-gecidi-yonlendirme-ve-toplama'
course: 'Trafik Katmanı'
language: tr
updated: '2026-08-17T18:11:03+00:00'
license: 'CC BY-SA 4.0'
---

# Ağ Geçidi Yönlendirme ve Toplama

Servis haritasının iki ayrı işi: yolun tek servise çevrilmesi ve tek isteğin birden çok servise dağıtılıp yanıtların tek gövdede birleştirilmesi; üç erişim biçiminin yerel süreçlerle ölçülmesi ve toplamanın istek sayısını yarıya indirirken uçtaki gövdeyi kaç kat büyüttüğünün hesaplanması.

Önceki ders ağ geçidinin bir servis haritası taşıdığını söyledi ama haritayı bir varsayım
olarak bıraktı. Harita iki ayrı iş yapabilir. Birincisi **ağ geçidi yönlendirme** (gateway
routing): gelen yol tek bir servise çevrilir, istemci arkadaki bölünmeyi görmez. İkincisi
**ağ geçidi toplama** (gateway aggregation): tek istek birden çok servise dağıtılır ve gelen
yanıtlar tek gövdede birleştirilir.

Ayrımın somut hâli takip sayfasıdır. Sayfa bir gönderinin durumunu teslimat operasyonu
bağlamından, ücretini ise ücretlendirme bağlamından alır. İki bağlam iki ayrı servistir, yani
sayfa iki yanıt ister. Bu ders o iki yanıtın kaç istekle, kaç baytla ve kaç turla alındığını
gerçek yerel süreçlerle ölçer; sonra ölçülen oranı Kabaca Büyüklük Hesabı dersinin takip
yanıtı sayısına uygular.

## Düzenek

İki alan servisi ve bir ağ geçidi ayrı süreçler olarak koşar. Servislerin döndürdüğü alan
kümesi Web API Tasarımı kursundaki kaynak tasarımı kurallarına göre belirlenmiştir ve burada
yeniden tartışılmaz; ölçülen şey kenarda verilen karardır.

```js
// gecit/servis.mjs — iki alan servisi: teslimat operasyonu 8471, ucretlendirme 8472
import { createServer } from "node:http";

const DURUM = {
  "TR-4821": { durum: "dagitimda", bolge: "35", guncellenme: "2026-03-11T08:24:00Z",
    rota: ["34", "41", "35"] },
  "TR-9007": { durum: "kabul", bolge: "34", guncellenme: "2026-03-11T07:02:00Z", rota: ["34"] },
};
const UCRET = {
  "TR-4821": { tarife: 9600, indirim: 1440, net: 8160, sozlesmeNo: "S7" },
};

const sun = (port, ad, tablo) => createServer((istek, yanit) => {
  const no = istek.url.split("/").pop();
  const kayit = tablo[no];
  const govde = JSON.stringify(kayit ? { takipNo: no, ...kayit } : { hata: "bulunamadi" });
  yanit.writeHead(kayit ? 200 : 404, { "Content-Type": "application/json" });
  yanit.end(govde);
}).listen(port, "127.0.0.1", () => console.log(`${ad} 127.0.0.1:${port}`));

sun(8471, "teslimat-op  ", DURUM);
sun(8472, "ucretlendirme", UCRET);
```

Ağ geçidi haritayı bir nesne olarak tutar ve iki yolu ayırır: `/takip/<no>/<alt>` bir servise
çevrilir, `/takip/<no>` ise iki servisi tek turda çağırır. Üçüncü bir yol, `/sayac`, geçit ile
servisler arasındaki sayaçları okuyup sıfırlar; ölçüm ucudur, tasarımın parçası değildir.

```js
// gecit/gecit.mjs — ag gecidi 8473: servis haritasiyla yonlendirme ve tek istekte toplama
import { createServer } from "node:http";

const HARITA = { durum: 8471, ucret: 8472 };      // yol parcasi -> servis
let sayac = { istek: 0, bayt: 0, tur: 0 };        // gecit ile servisler arasindaki sayaclar

async function servis(ad, no) {
  sayac.istek += 1;
  const y = await fetch(`http://127.0.0.1:${HARITA[ad]}/${ad}/${no}`);
  const metin = await y.text();
  sayac.bayt += Buffer.byteLength(metin);
  return y.ok ? JSON.parse(metin) : null;
}

createServer(async (istek, yanit) => {
  const [kok, no, alt] = istek.url.split("/").filter(Boolean);
  let govde;
  if (kok === "sayac") {                           // olcum ucu: sayaclari okur ve sifirlar
    govde = sayac;
    sayac = { istek: 0, bayt: 0, tur: 0 };
  } else if (kok !== "takip") {
    govde = null;
  } else if (alt) {                                // yonlendirme: yol tek servise cevrilir
    sayac.tur += 1;
    govde = await servis(alt, no);
  } else {                                         // toplama: iki servis tek turda cagrilir
    sayac.tur += 1;
    const [durum, ucret] = await Promise.all([servis("durum", no), servis("ucret", no)]);
    govde = durum && { ...durum, ucret: ucret && { tarife: ucret.tarife,
      indirim: ucret.indirim, net: ucret.net, sozlesmeNo: ucret.sozlesmeNo } };
  }
  const metin = JSON.stringify(govde ?? { hata: "bulunamadi" });
  yanit.writeHead(govde ? 200 : 404, { "Content-Type": "application/json" });
  yanit.end(metin);
}).listen(8473, "127.0.0.1", () => console.log("ag-gecidi     127.0.0.1:8473"));
```

İstemci üç erişim biçimini sırayla dener ve her birinde altı sayı toplar. Bayt sayıları yalnız
gövdeyi sayar; başlık ve protokol yükü K01'in hesabında da dışarıda bırakılmıştı.

```js
// gecit/olc.mjs — uc erisim bicimini olcer ve K01'in takip yaniti hesabina baglar
const al = async (url) => {
  const y = await fetch(url);
  const metin = await y.text();
  return { bayt: Buffer.byteLength(metin), veri: y.ok ? JSON.parse(metin) : null };
};
const sayacOku = async () => (await al("http://127.0.0.1:8473/sayac")).veri;
const yaprak = (d) => (typeof d !== "object" || d === null ? 1
  : Object.values(d).reduce((t, v) => t + yaprak(v), 0));

async function olc(ad, adres, istekler) {
  await sayacOku();                                   // onceki senaryonun sayaclarini sifirlar
  let bayt = 0, alan = 0;
  for (const u of istekler) {
    const r = await al(u);
    bayt += r.bayt;
    alan += r.veri ? yaprak(r.veri) : 0;
  }
  const ic = await sayacOku();
  return { ad, "istemci istegi": istekler.length, "istemcinin bildigi adres": adres,
    "istemciye ulasan bayt": bayt, "tasinan alan": alan,
    "gecit-servis istegi": ic.istek, "gecit-servis bayt": ic.bayt,
    "gecit turu": ic.tur };
}

const N = "TR-4821";
const S = [
  await olc("ayri cagri", 2, [`http://127.0.0.1:8471/durum/${N}`, `http://127.0.0.1:8472/ucret/${N}`]),
  await olc("yonlendirme", 1, [`http://127.0.0.1:8473/takip/${N}/durum`,
    `http://127.0.0.1:8473/takip/${N}/ucret`]),
  await olc("toplama", 1, [`http://127.0.0.1:8473/takip/${N}`]),
];
const ALAN = ["istemci istegi", "istemcinin bildigi adres", "istemciye ulasan bayt",
  "tasinan alan", "gecit-servis istegi", "gecit-servis bayt", "gecit turu"];
console.log(`${"olcu".padEnd(26)}${S.map((s) => s.ad.padStart(13)).join("")}`);
for (const a of ALAN) console.log(`${a.padEnd(26)}${S.map((s) => String(s[a]).padStart(13)).join("")}`);

// Eksik parca: ucretlendirme bu takip numarasini tanimiyor
const eksik = await al(`http://127.0.0.1:8473/takip/TR-9007`);
console.log(`\neksik parcali toplama = ${eksik.bayt} bayt, tasinan alan = ${yaprak(eksik.veri)}`);
console.log(`  govde: ${JSON.stringify(eksik.veri)}`);

// K01 Kabaca Buyukluk Hesabi: V5 = 480 bayt (varsayim), okuma tepesi 416.67 istek/s (hesap)
const durumBayt = (await al(`http://127.0.0.1:8471/durum/${N}`)).bayt;
const ucretBayt = (await al(`http://127.0.0.1:8472/ucret/${N}`)).bayt;
const birlesik = (await al(`http://127.0.0.1:8473/takip/${N}`)).bayt;
const V5 = 480, OKUMA_TEPE = 416.67;
const mbit = (istek, bayt) => (istek * bayt * 8) / 1e6;
console.log(`\ndurum ${durumBayt} B, ucret ${ucretBayt} B, birlesik ${birlesik} B`);
console.log(`oran — ucret/durum = ${(ucretBayt / durumBayt).toFixed(3)}, ` +
  `birlesik/durum = ${(birlesik / durumBayt).toFixed(3)}`);
const KURULUM = [
  ["K01 (yalniz durum)", OKUMA_TEPE, V5],
  ["ayri cagri", OKUMA_TEPE * 2, (V5 * (durumBayt + ucretBayt)) / durumBayt / 2],
  ["toplama", OKUMA_TEPE, (V5 * birlesik) / durumBayt],
];
console.log(`${"kurulum".padEnd(20)}${"istek/s".padStart(10)}${"bayt".padStart(9)}${"Mbit/s".padStart(9)}`);
for (const [ad, istek, bayt] of KURULUM) {
  console.log(`${ad.padEnd(20)}${istek.toFixed(2).padStart(10)}${bayt.toFixed(0).padStart(9)}` +
    `${mbit(istek, bayt).toFixed(2).padStart(9)}`);
}
const [, ayri, top] = KURULUM;
console.log(`toplama / ayri cagri — istek x${(top[1] / ayri[1]).toFixed(2)}, ` +
  `cikis x${(mbit(top[1], top[2]) / mbit(ayri[1], ayri[2])).toFixed(2)}`);

// T1 duyarliligi: goruntulemelerin yalniz bir bolumu ucret istiyorsa (T1 = 0.40)
const T1 = 0.4;
const ayriIstek = OKUMA_TEPE * (1 + T1);
const ayriBayt = (V5 * (durumBayt + T1 * ucretBayt)) / durumBayt / (1 + T1);
const topBayt = (V5 * (durumBayt + T1 * (birlesik - durumBayt))) / durumBayt;
console.log(`T1 = ${T1.toFixed(2)} -> ayri cagri ${ayriIstek.toFixed(2)} istek/s ` +
  `${mbit(ayriIstek, ayriBayt).toFixed(2)} Mbit/s | toplama ${OKUMA_TEPE.toFixed(2)} istek/s ` +
  `${mbit(OKUMA_TEPE, topBayt).toFixed(2)} Mbit/s`);
```

```bash
node gecit/servis.mjs & s=$!
curl -s --retry 20 --retry-connrefused --retry-delay 0 -o /dev/null http://127.0.0.1:8472/ucret/TR-4821
node gecit/gecit.mjs & g=$!
curl -s --retry 20 --retry-connrefused --retry-delay 0 -o /dev/null http://127.0.0.1:8473/sayac
node gecit/olc.mjs
kill $s $g
```

```
teslimat-op   127.0.0.1:8471
ucretlendirme 127.0.0.1:8472
ag-gecidi     127.0.0.1:8473
olcu                         ayri cagri  yonlendirme      toplama
istemci istegi                        2            2            1
istemcinin bildigi adres              2            1            1
istemciye ulasan bayt               194          194          183
tasinan alan                         12           12           11
gecit-servis istegi                   0            2            2
gecit-servis bayt                     0          194          194
gecit turu                            0            2            1

eksik parcali toplama = 114 bayt, tasinan alan = 6
  govde: {"takipNo":"TR-9007","durum":"kabul","bolge":"34","guncellenme":"2026-03-11T07:02:00Z","rota":["34"],"ucret":null}

durum 115 B, ucret 79 B, birlesik 183 B
oran — ucret/durum = 0.687, birlesik/durum = 1.591
kurulum                istek/s     bayt   Mbit/s
K01 (yalniz durum)      416.67      480     1.60
ayri cagri              833.34      405     2.70
toplama                 416.67      764     2.55
toplama / ayri cagri — istek x0.50, cikis x0.94
T1 = 0.40 -> ayri cagri 583.34 istek/s 2.04 Mbit/s | toplama 416.67 istek/s 1.98 Mbit/s
```

## Yönlendirme Tek Başına Ne Kazandırır

Tablonun ilk iki kolonu bunu yanıtlıyor: yönlendirmeye geçildiğinde istemci isteği 2'de,
istemciye ulaşan bayt 194'te, taşınan alan 12'de kalıyor. Değişen tek sayı istemcinin bildiği
adres: 2 yerine 1. Yönlendirme bir başarım kararı değil, bir **bağ** kararıdır. Servis
haritası ağ geçidinde durduğu için ücretlendirme servisi başka bir adrese taşındığında ya da
iki servise bölündüğünde istemci düzenlenmez; harita düzenlenir.

Karşılığında `gecit-servis istegi` 0'dan 2'ye çıkıyor. Aynı iki çağrı hâlâ yapılıyor, yalnız
kenarın arkasına geçmiş durumda. Yönlendirme bir çağrıyı ortadan kaldırmaz; kimin yaptığını
değiştirir.

## Toplama Neyi Değiştirir

Üçüncü kolon dört sayıyı birden oynatıyor. İstemci isteği 2'den 1'e, taşınan alan 12'den
11'e, istemciye ulaşan bayt 194'ten 183'e ve geçit turu 2'den 1'e iniyor. Alan sayısının
düşmesi `takipNo` alanının iki gövdede birden taşınmaktan tek gövdeye inmesindendir; 11 baytlık
azalma da bundandır. Geçit turunun 1'e inmesi ise iki çağrının tek turda, birbirini beklemeden
yapılmasıdır; iki servisten yanıt gelmesini bekleyen taraf istemci değil ağ geçididir.

Değişmeyen sayı önemli: `gecit-servis istegi` toplamada da 2. Toplama, sistemin yaptığı çağrı
sayısını düşürmez — **kenarın dışında görünen** çağrı sayısını düşürür. Bu ayrım kararın nereye
yazılacağını belirler: kazanç istemci tarafındaki tur sayısında ve istemcinin taşıdığı
bilgide, maliyet ise ağ geçidinin iki yanıtı bekleyen kodunda.

## Eksik Parça Bir Sözleşme Kararıdır

`TR-9007` numaralı gönderinin ücretlendirme kaydı yok. Toplama bu durumda 114 baytlık bir
gövde ve 6 alan döndürüyor; `ucret` alanı `null`. Bu, kodun bir seçimidir ve seçenekleri
sayılabilir: birleşik yanıt eksik parçayla dönebilir, tümüyle başarısız sayılabilir ya da
eksik parça istemciye ayrı bir alanda bildirilebilir. Toplama yapan bir ağ geçidi bu seçimi
yapmak zorundadır, çünkü artık tek bir yanıtın içinde birden çok kaynağın durumu vardır. Bu
sözleşme kararı yazılmadığında istemci, eksik `ucret` alanını "ücret sıfır" ile
karıştırabilir. Kararın kendisi ağ geçidine değil, iki tarafın anlaştığı yanıt biçimine
aittir.

## Hesaba Dönüş

K01'in varsayım tablosunda V5 takip yanıtını 480 bayt sayıyordu ve gerekçesi "durum, bölge,
güncellenme zamanı ve son üç rota adımı"ydı — yani yalnız durum parçası. Takip sayfasının
ücreti de göstermesi K01'de yoktu; bu **bu kursun varsayımıdır** (T1 = 1,00: her takip
görüntülemesi ücret bilgisini de ister). Gerekçesi sayfanın tek ekranda iki bilgiyi
göstermesidir; duyarlılığı aşağıda hesaplandı.

Düzenekten ölçülen oranlar belirlenimlidir: gövdeler JSON metnidir, bayt sayıları makineden
bağımsızdır. Ücret gövdesi durum gövdesinin 0,687 katı, birleşik gövde 1,591 katı. Bu oranlar
V5'e uygulandığında üç kurulum çıkıyor. K01'in kendi satırı 416,67 istek/s ve 480 bayt ile
1,60 Mbit/s. Ayrı çağrıda istek hızı ikiye katlanıyor (833,34) ve istek başına ortalama gövde
405 bayta düşüyor; çıkış 2,70 Mbit/s. Toplamada istek hızı 416,67'de kalıyor ama gövde 764
bayta çıkıyor; çıkış 2,55 Mbit/s.

Üç sayı üç ayrı şey söylüyor. Birincisi toplama istek hızını yarıya indiriyor (×0,50) ama
çıkışı yalnız 0,94 katına indiriyor: bant genişliğini belirleyen şey paketleme değil, taşınan
alan kümesidir. İkincisi K01'in 1,60 Mbit/s'i her iki kurulumda da aşılıyor; gereksinim
büyüdüğünde hesap yeniden koşturulur, eski sayı korunmaz. Üçüncüsü T1'in duyarlılığı: yalnız
görüntülemelerin yüzde kırkı ücret istiyorsa ayrı çağrıda 583,34 istek/s ve 2,04 Mbit/s,
toplamada 416,67 istek/s ve 1,98 Mbit/s çıkıyor. Toplamanın istek hızı kazancı T1 küçüldükçe
azalır; gövde büyütme bedeli de azalır.

## Özet

- Servis haritası iki iş yapar: yönlendirme yolu tek servise çevirir, toplama tek isteği
  birden çok servise dağıtıp yanıtları birleştirir.
- Yönlendirme yalnız bağ kararıdır: istemci isteği 2, bayt 194 ve alan 12 sabit kalırken
  istemcinin bildiği adres 2'den 1'e iniyor, `gecit-servis istegi` 0'dan 2'ye çıkıyor.
- Toplama istemci isteğini 2'den 1'e, taşınan alanı 12'den 11'e, geçit turunu 2'den 1'e
  indiriyor; geçit ile servisler arasındaki istek sayısı 2'de kalıyor.
- Toplamanın döndürdüğü gövdede birden çok kaynağın durumu birleşir; eksik parçanın nasıl
  bildirileceği bir sözleşme kararıdır — örnekte eksik parça `null` ile döndü, gövde 114 bayt
  ve 6 alan.
- Ölçülen oranlar: ücret gövdesi durum gövdesinin 0,687 katı, birleşik gövde 1,591 katı; bayt
  sayıları makineden bağımsızdır.
- K01'e dönüş: 416,67 istek/s ve 480 bayt ile 1,60 Mbit/s olan çıkış, ayrı çağrıda 833,34
  istek/s ve 2,70 Mbit/s, toplamada 416,67 istek/s ve 2,55 Mbit/s oluyor — istek ×0,50, çıkış
  ×0,94.

## Sonraki Adım

Toplama, ağ geçidinin gövdeye dokunan ilk işiydi ve bir sözleşme kararı gerektirdi. Kenara
taşınabilecek işlerin çoğu ise gövdeye hiç dokunmaz: bir belirtecin doğrulanması, bir hız
sınırının uygulanması, bir erişim kaydının yazılması. Bu işler her serviste tekrarlanabilir
ya da tek bir yerde toplanabilir; ilk ders ikisini satır sayısıyla karşılaştırdı ama hangi
işin taşınabilir olduğunu bir kurala bağlamadı. Sonraki ders o kuralı kurar: bir denetimin
okuduğu girdiler yazıldığında, kenara taşınabilenler ile serviste kalması gerekenler mekanik
olarak ayrılır — ve doğrulamanın tek yerde yapılmasının uygulamaya ne ödettiği ölçülür.
