---
title: 'Mesaj Kuyrukları'
source: 'https://academia.sh/tr/kurslar/uygulama-katmani/mesaj-kuyruklari'
course: 'Uygulama Katmanı ve Servis Etkileşimi'
language: tr
updated: '2026-08-17T18:10:55+00:00'
license: 'CC BY-SA 4.0'
---

# Mesaj Kuyrukları

Kuyruğun bir kapasite kararı olarak ele alınması: eşzamanlı yazma yolunda kapasitenin anlık tepeye göre seçilmesi, kuyruk konduğunda işleme kapasitesinin ortalamaya yaklaştırılması, kazancın birikme ve bekleme cinsinden ödenmesi, deponun kısa bir kesintisinde iki tasarımın kayıp sayısıyla karşılaştırılması ve depoya ulaşan istek hızının yeniden hesaplanması.

Önceki konu eşzamanlı çağrıyı tasarladı: çağıran bekler, bir zaman aşımı bütçesi işler, sürenin
sonunda ya bir yanıt gelir ya bir hata. Konunun son dersi o bütçenin aritmetiğini çıkardı ve bir
sınırı görünür kıldı — zincir uzadıkça ya bütçe parçalara bölünür ve her adım daralır, ya da
uçtan uca süre büyür. İki seçenek de aynı varsayımın içindedir: çağıran işin sonucunu bekliyor.
Bazı işler için üçüncü bir yol vardır ve o yol varsayımı kaldırır — çağıran hiç beklemez.
Taşıyıcıdan gelen durum olayının deponun içine yazılması, isteği yanıtlamak için tamamlanmak
zorunda değildir.

Bu konu o yolu ele alır. **Mesaj kuyruğu** (message queue) mekaniği Önbellekleme, Kuyruklar ve
Eşzamansız İşleme kursunda kuruldu ve ölçüldü: üreticinin yazması, tüketicinin alması, onay,
görünmezlik süresi, teslim garantileri, tüketici grupları, sıralama ve ölü mektup kuyruğu. Burada
hiçbiri yeniden anlatılmaz. Bu kursun sorusu başkadır ve tek cümleyle söylenir: **kuyruk bir
kapasite kararıdır.** Yük zamana yayıldığında ne kazanılır, ne ödenir ve giriş kursunun hangi
sayısı değişir.

## Kapasite Hangi Sayıya Göre Seçilir

Eşzamanlı yazma yolunda bir kural vardır ve tartışılmaz: kapasite **anlık tepe** hızına göre
seçilir. Taşıyıcı bir durum olayı gönderip yanıt bekliyorsa, o anda gelen her isteğin işlenecek
bir yeri olmalıdır; olmayan istek reddedilir. Sistem Tasarımına Giriş kursunun Kabaca Büyüklük
Hesabı dersi bu sayıyı veriyor: **tepe yazma 97,22 istek/s** — hesap sınıfı, günde 2.800.000
durum olayından, gün ortalaması 32,41 istek/s ve V8 tepe çarpanı 3'ten çıkıyor.

Kuyruk bu kuralı ikiye böler. Taşıyıcının konuştuğu uç yine tepeyi kabul etmek zorundadır, ama
orada yaptığı iş tek bir ekleme işlemine iner: olayı kuyruğa yaz, onayı dön. Olayın asıl işlenmesi
— gönderi kaydının güncellenmesi, rota adımının yazılması, ücretlendirme satırının hazırlanması —
kuyruğun arkasına geçer ve orada kapasite **seçilebilir** hale gelir. Seçim özgürlüğü kuyruğun
kazancıdır; sınırı da kuyruğun kendisidir, çünkü tüketilmeyen her olay birikir.

Birikmeyi hesaplamak için K01'in tablosunda olmayan bir sayı gerekir. V8 tepenin ne kadar
**yüksek** olduğunu söylüyor, ne kadar **sürdüğünü** söylemiyor.

**K1 — tepe penceresi: 3 saat/gün.** Bu kursun kendi varsayımıdır ve K01'in tablosuna eklenmez.
Gerekçe: durum olaylarını taşıyıcıların dağıtım turu üretir ve tur günün belirli bir dilimine
sıkışır. Günlük toplam K01'den geldiği için tepe dışı hız artık serbest değildir: üç saat 97,22
istek/s ile 1.050.000 olay üretir, kalan 1.750.000 olay yirmi bir saate yayılır ve tepe dışı hız
23,15 istek/s olur. Duyarlılığı aşağıdaki ikinci tabloda ölçülüyor.

## Birikme

Aşağıdaki düzenek kuyruğu, üreticiyi ve tüketiciyi süreç içi birer modül olarak kurar. Tur bir
saniyedir; bir günü saniye saniye yürütür ve seçilen işleme kapasitesine göre birikmeyi izler.
**Bu bir modeldir**, ölçüm değildir: içindeki bütün sayılar K01'den ve K1'den aritmetikle çıkar,
sonuçlar belirlenimlidir ve makineden bağımsızdır — yani hesap sınıfındadır. Başlangıç birikmesi
dönemsel olsun diye dört gün koşulur ve sayılar üçüncü günden alınır.

```js
// kuyruk/yayma.mjs — gunluk olay profilinin sabit kapasiteli bir tuketiciye verilmesi.
// MODEL: kuyruk ve tuketici surec ici birer modul, tur bir saniyedir. Sonuclar belirlenimlidir
// (hesap sinifi) ve makineden bagimsizdir; olculmus sure yoktur.
const GUN = 86_400;
const GUNLUK_OLAY = 2_800_000;     // K01 Kabaca Buyukluk Hesabi: gunluk durum olayi
const TEPE_CARPANI = 3;            // K01 varsayim V8
const TEPE_BAS = 9 * 3600;         // tepe penceresinin gun icindeki yeri
const ESIK = 300;                  // "geciken olay" esigi (s)

function profil(tepeSaat) {
  const ortalama = GUNLUK_OLAY / GUN;
  const tepe = ortalama * TEPE_CARPANI;
  const tepeSn = tepeSaat * 3600;
  const disi = (GUNLUK_OLAY - tepe * tepeSn) / (GUN - tepeSn);
  return { ortalama, tepe, disi,
    varis: (t) => (t >= TEPE_BAS && t < TEPE_BAS + tepeSn ? tepe : disi) };
}

function kosum(kapasite, p) {       // dort gun kosar; ilk iki gun baslangic birikmesini
  let birikme = 0;                  // donemsel hale getirir, sayilar ucuncu gunden alinir
  let enYuksek = 0, toplam = 0, geciken = 0, bosalma = -1;
  const OLC = 2 * GUN;              // olcum gununun baslangici
  for (let t = 0; t < 4 * GUN; t += 1) {
    const gelen = p.varis(t % GUN);
    if (t >= OLC && t < OLC + GUN) {
      if (birikme / kapasite > ESIK) geciken += gelen;
      toplam += gelen;
    }
    birikme += gelen;
    birikme -= Math.min(birikme, kapasite);
    if (t >= OLC && t < OLC + GUN && birikme > enYuksek) enYuksek = birikme;
    if (bosalma < 0 && t > OLC + TEPE_BAS && birikme < 1) bosalma = t - OLC - TEPE_BAS;
  }
  return { enYuksek, bosalma, geciken, oran: geciken / toplam,
    bekleme: enYuksek / kapasite };
}

function tablo(tepeSaat) {
  const p = profil(tepeSaat);
  console.log(`K1 = ${tepeSaat} saat tepe penceresi -> tepe ${p.tepe.toFixed(2)}/s, ` +
    `tepe disi ${p.disi.toFixed(2)}/s, ortalama ${p.ortalama.toFixed(2)}/s`);
  console.log("kapasite  tepeye oran  en yuksek birikme  en uzun bekleme  bosalma  geciken olay  geciken oran");
  for (const oran of [1, 2 / 3, 0.5, 0.4, 0.35, 1 / 3]) {
    const k = p.tepe * oran;
    const r = kosum(k, p);
    const b = r.bekleme < 3600 ? `${(r.bekleme / 60).toFixed(1)} dk` : `${(r.bekleme / 3600).toFixed(2)} sa`;
    const s = r.bosalma < 0 ? "yok" : `${(r.bosalma / 3600).toFixed(2)} sa`;
    console.log(`${k.toFixed(2).padStart(8)}  ${oran.toFixed(2).padStart(11)}  ` +
      `${r.enYuksek.toFixed(0).padStart(17)}  ${b.padStart(15)}  ${s.padStart(7)}  ` +
      `${r.geciken.toFixed(0).padStart(12)}  ${r.oran.toFixed(3).padStart(11)}`);
  }
}

console.log(`gunde ${GUNLUK_OLAY} durum olayi (K01), tepe carpani ${TEPE_CARPANI} (V8)`);
console.log(`"geciken olay" = ${ESIK} saniyeden uzun bekleyen olay\n`);
tablo(3);
console.log();
tablo(6);
```

```
gunde 2800000 durum olayi (K01), tepe carpani 3 (V8)
"geciken olay" = 300 saniyeden uzun bekleyen olay

K1 = 3 saat tepe penceresi -> tepe 97.22/s, tepe disi 23.15/s, ortalama 32.41/s
kapasite  tepeye oran  en yuksek birikme  en uzun bekleme  bosalma  geciken olay  geciken oran
   97.22         1.00                  0           0.0 dk  0.00 sa             0        0.000
   64.81         0.67             350000          1.50 sa  5.33 sa       1175324        0.420
   48.61         0.50             525000          3.00 sa  8.73 sa       1484861        0.530
   38.89         0.40             630000          4.50 sa  14.12 sa       1939884        0.693
   34.03         0.35             682500          5.57 sa  20.43 sa       2464667        0.880
   32.41         0.33             700000          6.00 sa  24.00 sa       2761134        0.986

K1 = 6 saat tepe penceresi -> tepe 97.22/s, tepe disi 10.80/s, ortalama 32.41/s
kapasite  tepeye oran  en yuksek birikme  en uzun bekleme  bosalma  geciken olay  geciken oran
   97.22         1.00                  0           0.0 dk  0.00 sa             0        0.000
   64.81         0.67             700000          3.00 sa  9.60 sa       2177789        0.778
   48.61         0.50            1050000          6.00 sa  13.71 sa       2366670        0.845
   38.89         0.40            1260000          9.00 sa  18.46 sa       2560693        0.915
   34.03         0.35            1365000         11.14 sa  22.33 sa       2714390        0.969
   32.41         0.33            1400000         12.00 sa  24.00 sa       2780556        0.993
```

## Ne Kazanıldı, Ne Ödendi

Birinci tablonun ilk satırı eşzamanlı tasarımın kendisidir: kapasite tepeye eşitse birikme sıfır,
bekleme sıfır. Aşağı inen her satır kapasiteden vazgeçip bekleme satın alıyor.

**Kazanç doğrusal.** Kapasite tepenin yarısına indiğinde işleme tarafı yarı yarıya küçülür;
üçte birine indiğinde üçte birine iner. Alt sınır tesadüf değildir: tepenin üçte biri gün
ortalamasıdır ve V8'in tanımı gereği tepe ortalamanın üç katıdır. **Kuyruğun kapasite kazancının
üst sınırı tepe çarpanının kendisidir** — tepeye göre değil ortalamaya göre boyutlanmak, V8 kadar
kazanç demektir ve daha fazlası yoktur.

**Bedel doğrusal değil.** Kapasite 1,00'den 0,67'ye inerken en yüksek birikme 0'dan 350.000'e
çıkıyor; 0,50'ye inerken 525.000'e, 0,40'a inerken 630.000'e. Kapasitenin son yüzde on yediyi
vermesi birikmeye 105.000 eklerken, ilk yüzde otuz üç 350.000 ekledi — ama beklemeye bakıldığında
sıra tersine döner: en uzun bekleme 1,50 saatten 3,00, sonra 4,50 saate çıkıyor. Bekleme,
birikmenin kapasiteye bölümü olduğu için pay büyürken payda küçülüyor ve iki etki çarpışıyor.
Ortalamaya en yakın satırda bekleme altı saattir.

**Boşalma sütunu bir sınır çiziyor.** Kapasite 0,35 katında birikme tepeden 20,43 saat sonra
sıfırlanıyor; 0,33 katında tam 24,00 saat sürüyor, yani ertesi günün tepesi başladığı anda
sıfırlanıyor. Bu bir bıçak sırtıdır: ortalamaya eşit kapasite seçen bir tasarımda tek bir yoğun
gün, ertesi güne devreden bir birikme bırakır ve birikme günden güne büyür. **Ortalamaya göre
boyutlanmak kuramsal sınırdır, seçilebilir bir tasarım değildir.**

**Geciken olay sütunu bedelin kimi etkilediğini söylüyor.** Beş dakikadan uzun bekleyen olay
sayısı 0,67 katında 1.175.324, yani günün olaylarının yüzde 42'si. Yarım kapasitede yüzde 53'e,
0,40 katında yüzde 69'a çıkıyor. Bu sayı doğrudan takip sorgusunun gördüğü tazeliktir: taşıyıcı
"dağıtıma çıktı" olayını gönderdiğinde alıcının takip sayfası onu ancak birikme boşaldığında
gösterir.

**İkinci tablo K1'in duyarlılığıdır.** Tepe penceresi üç saatten altı saate çıktığında tepe hızı
değişmiyor — o sayı V8'den geliyor — ama tepe dışı hız 23,15'ten 10,80 istek/s'ye iniyor ve
birikmeler tam iki katına çıkıyor: 0,50 katında 525.000 yerine 1.050.000, bekleme üç saat yerine
altı saat. Varsayımın tasarıma etkisi doğrudandır ve tek yönlüdür: **tepenin süresi, tepenin
yüksekliği kadar belirleyicidir** ve K01'in tablosu bu bilgiyi taşımıyordu.

## Kesinti Karşısında İki Tasarım

Kapasite kararı tabloya bakarak kuyruk aleyhine sonuçlanabilir. Eksik olan bir ölçü var: kuyruk
yalnız yükü zamana yaymaz, üreticiyi tüketicinin arızasından da ayırır. İkinci düzenek deponun
tepe penceresinin ortasında on beş dakika yazma kabul etmediği durumu ekler. Kesinti bir
parametredir.

```js
// kuyruk/kesinti.mjs — deponun 15 dakika yazma kabul etmedigi durumda iki tasarimin
// karsilastirilmasi. MODEL: tur bir saniyedir, kesinti parametreyle tetiklenir.
// Sonuclar belirlenimlidir (hesap sinifi).
const GUN = 86_400;
const GUNLUK_OLAY = 2_800_000;     // K01: gunluk durum olayi
const TEPE = (GUNLUK_OLAY / GUN) * 3;               // K01 hesabi + V8: tepe yazma /s
const TEPE_BAS = 9 * 3600, TEPE_SN = 3 * 3600;      // K1: 3 saatlik tepe penceresi
const DISI = (GUNLUK_OLAY - TEPE * TEPE_SN) / (GUN - TEPE_SN);
const KESINTI_BAS = 10 * 3600, KESINTI_SN = 900;    // kesinti tepe penceresinin ortasinda

const varis = (t) => (t >= TEPE_BAS && t < TEPE_BAS + TEPE_SN ? TEPE : DISI);
const kesik = (t) => t >= KESINTI_BAS && t < KESINTI_BAS + KESINTI_SN;

function kosum(kapasite, kuyrukVar, kesintiVar) {
  let birikme = 0, kayip = 0, enYuksek = 0, bosalma = -1;
  for (let t = 0; t < 2 * GUN; t += 1) {
    const gun = t % GUN;
    const gelen = varis(gun);
    const kap = kesintiVar && kesik(gun) ? 0 : kapasite;
    if (kuyrukVar) birikme += gelen;
    else if (gelen > kap) { kayip += (gelen - kap) * (t >= GUN ? 1 : 0); }
    birikme -= Math.min(birikme, kap);
    if (t >= GUN) {
      if (birikme > enYuksek) enYuksek = birikme;
      if (bosalma < 0 && gun > TEPE_BAS && birikme < 1) bosalma = gun - TEPE_BAS;
    }
  }
  return { kayip, enYuksek, bosalma, bekleme: enYuksek / kapasite };
}

const bicim = (r, kapasite) => `${kapasite.toFixed(2).padStart(8)}  ` +
  `${r.kayip.toFixed(0).padStart(15)}  ${r.enYuksek.toFixed(0).padStart(17)}  ` +
  `${(r.bekleme / 3600).toFixed(2).padStart(13)}  ` +
  `${(r.bosalma < 0 ? NaN : r.bosalma / 3600).toFixed(2).padStart(13)}`;

console.log(`kesinti: ${KESINTI_SN} s, tepe penceresinin icinde; o sirada gelen olay ` +
  `${(TEPE * KESINTI_SN).toFixed(0)}\n`);
console.log("tasarim                 kapasite  kaybedilen olay  en yuksek birikme  bekleme (sa)  bosalma (sa)");
console.log(`${"eszamanli yazma".padEnd(22)} ${bicim(kosum(TEPE, false, false), TEPE)}`);
console.log(`${"eszamanli + kesinti".padEnd(22)} ${bicim(kosum(TEPE, false, true), TEPE)}`);
for (const oran of [0.5, 0.4]) {
  const k = TEPE * oran;
  console.log(`${`kuyruk ${oran.toFixed(2)}x tepe`.padEnd(22)} ${bicim(kosum(k, true, false), k)}`);
  console.log(`${`kuyruk ${oran.toFixed(2)}x + kesinti`.padEnd(22)} ${bicim(kosum(k, true, true), k)}`);
}

const ONBELLEK_ARKASI = 41.67;     // K01: onbellek arkasi okuma/s
const DEPO_TABAN = 138.89;         // K01: depoya ulasan istek/s
console.log(`\nK01 donusu: depoya ulasan istek/s, taban ${DEPO_TABAN} (okuma ${ONBELLEK_ARKASI} + yazma ${TEPE.toFixed(2)})`);
for (const oran of [1, 0.5, 0.4]) {
  const k = TEPE * oran, depo = ONBELLEK_ARKASI + k;
  console.log(`  isleme kapasitesi ${k.toFixed(2).padStart(6)}/s -> depoya ulasan ${depo.toFixed(2).padStart(6)}/s, ` +
    `tabanin ${(depo / DEPO_TABAN).toFixed(2)} kati, depoda yazma/okuma ${(k / ONBELLEK_ARKASI).toFixed(2)}`);
}
```

```
kesinti: 900 s, tepe penceresinin icinde; o sirada gelen olay 87500

tasarim                 kapasite  kaybedilen olay  en yuksek birikme  bekleme (sa)  bosalma (sa)
eszamanli yazma           97.22                0                  0           0.00           0.00
eszamanli + kesinti       97.22            87500                  0           0.00           0.00
kuyruk 0.50x tepe         48.61                0             525000           3.00           8.73
kuyruk 0.50x + kesinti    48.61                0             568750           3.25           9.20
kuyruk 0.40x tepe         38.89                0             630000           4.50          14.12
kuyruk 0.40x + kesinti    38.89                0             665000           4.75          14.73

K01 donusu: depoya ulasan istek/s, taban 138.89 (okuma 41.67 + yazma 97.22)
  isleme kapasitesi  97.22/s -> depoya ulasan 138.89/s, tabanin 1.00 kati, depoda yazma/okuma 2.33
  isleme kapasitesi  48.61/s -> depoya ulasan  90.28/s, tabanin 0.65 kati, depoda yazma/okuma 1.17
  isleme kapasitesi  38.89/s -> depoya ulasan  80.56/s, tabanin 0.58 kati, depoda yazma/okuma 0.93
```

On beş dakikalık kesinti eşzamanlı tasarımda **87.500 olay** düşürüyor. Sayı doğrudan aritmetiktir:
900 saniye × 97,22 istek/s. Taşıyıcı yeniden denese bile o denemeler ayrı bir tasarım kararıdır
ve Dayanıklılık ve Güvenilirlik kursunda ele alındı; burada ölçülen, tasarımın kendi başına
kaybettiğidir.

Aynı kesinti kuyruklu tasarımda **sıfır olay** düşürüyor. Ödenen şey birikmeye eklenen 43.750
olay ve beklemeye eklenen on beş dakikadır: yarım kapasitede en yüksek birikme 525.000'den
568.750'ye, bekleme 3,00 saatten 3,25 saate, boşalma 8,73 saatten 9,20 saate çıkıyor. Bu bir
kıyaslama değil bir **dönüştürme**dir: kuyruk kaybı gecikmeye çevirir. Kaybın kabul edilemez
olduğu ve gecikmenin taşınabildiği akışlarda kazanç, tersi durumda zarar.

## Hesaba Geri Dönüş

Son üç satır K01'in bir hesabını yeniden yazıyor. Kabaca Büyüklük Hesabı dersi depoya ulaşan tepe
istek hızını 138,89 istek/s bulmuştu: önbelleğin arkasındaki 41,67 okuma artı 97,22 yazma. O
toplamdaki yazma payı eşzamanlı tasarımın varsayımıydı — her olay geldiği anda depoya yazılıyor.

Kuyruk yazma payını seçilebilir yapıyor. İşleme kapasitesi tepenin yarısında seçildiğinde depoya
ulaşan istek hızı 90,28 istek/s'ye iniyor, tabanın 0,65 katı; 0,40 katında 80,56 istek/s, tabanın
0,58 katı. Depodaki yazma/okuma oranı da değişiyor: K01'in 2,33 değeri sırasıyla 1,17 ve 0,93
oluyor. K01, deponun gördüğü yerde sistemin yazma ağırlıklı olduğunu bulmuştu; kuyruk bu dengeyi
tersine çevirebilecek bir karardır ve deponun boyutlandırılması bu yeni sayıdan başlar.

Karar tek satıra iner. Kuyruk üç koşul birlikte sağlandığında kapasite kazandırır: tepe ile
ortalama arasında gerçek bir fark vardır (V8 birden büyüktür), çağıranın sonucu beklemesi
gerekmez, ve işin etkisinin gecikmesi taşınabilir. Üçüncüsü en sık atlanandır; tablodaki "geciken
olay" sütunu onun bedelidir.

## Özet

- Eşzamanlı yazma yolunda kapasite anlık tepeye göre seçilir; K01'in tepe yazma hızı 97,22
  istek/s bu tasarımın gereksinimidir.
- Kuyruk kapasite kararını ikiye böler: kabul yolu tepeyi almak zorundadır, işleme kapasitesi
  seçilebilir; kazancın üst sınırı tepe çarpanı V8'dir, yani üç kat.
- Kazanç doğrusal, bedel değil: kapasite tepenin 0,67 / 0,50 / 0,40 katına indiğinde en yüksek
  birikme 350.000 / 525.000 / 630.000, en uzun bekleme 1,50 / 3,00 / 4,50 saat oluyor.
- Ortalamaya eşit kapasite bir bıçak sırtıdır: birikme tam 24,00 saatte boşalıyor ve olayların
  yüzde 98,6'sı beş dakikadan uzun bekliyor.
- K1 varsayımı duyarlıdır: tepe penceresi üç saatten altı saate çıktığında bütün birikmeler ve
  beklemeler iki katına çıkıyor, tepe hızı ise değişmiyor.
- Kuyruk kaybı gecikmeye çevirir: on beş dakikalık depo kesintisi eşzamanlı tasarımda 87.500
  olay düşürürken kuyruklu tasarımda sıfır olay düşürüyor, karşılığında bekleme 3,00 saatten
  3,25 saate çıkıyor.

## Sonraki Adım

Bu dersin bütün olayları birbirinin eşiydi: her durum olayı aynı büyüklükte, aynı işi yapan,
milisaniyeler süren bir kayıttı. Birikme hesabı da buna dayanıyordu — kapasite bir sayıdır çünkü
işler tek tiptir. Aynı sistemde bu varsayımın tutmadığı bir iş var: satıcının istediği dönem
raporu, binlerce gönderi kaydını tarar ve saniyelerce sürer. Böyle bir iş isteğin içinde
çalıştırıldığında yalnız kendi süresini harcamaz, arkasındaki kısa istekleri de bekletir. Sonraki
ders bu iki işi ayırır: uzun işin istek yolunda kalmasının kısa isteklere ne yaptığını ölçer ve
görev kuyruğuna alındığında hangi ölçünün düzeldiğini sayar.
