---
title: 'Süreç Yöneticileri'
source: 'https://academia.sh/tr/kurslar/backend-uretim/surec-yoneticileri'
course: 'Sunucu Güvenliği ve Üretime Alma'
language: tr
updated: '2026-08-17T18:06:49+00:00'
license: 'CC BY-SA 4.0'
---

# Süreç Yöneticileri

Uygulamanın altındaki katmanın iki ayarı: çöken sürecin anında, geri çekilmeli ve sınırlı denemeyle yeniden başlatılmasının düşen istek sayısına etkisi, hiç başlamayan süreçte başlatma döngüsünün politikaya göre kaç kez döndüğü, bellek sınırının aşılmasında sürecin öldürülmesi ile kayıt atıp ayakta kalması arasındaki fark ve durdurma işaretinden sonra tanınan bekleme süresinin boşaltılan istek sayısını nasıl belirlediği.

Önceki ders uygulamanın **önündeki** katmanı yapılandırdı ve sekiz koşumun hepsinde tek bir şeyi
varsaydı: uygulama süreci ayaktaydı. Elle başlatıldı, işi bitince elle durduruldu, arada hiç
çökmedi.

Üretimde süreci başlatan, çöktüğünde yeniden başlatan, ne kadar bellek kullanabileceğine karar veren
ve durdurulacağı zaman ona haber veren başka bir bileşen vardır: **süreç yöneticisi**. Vekilin
ayarları isteğin içeriğini değiştiriyordu; buranın ayarları isteğin **yanıtlanıp
yanıtlanmayacağını** değiştirir.

## İki Ayar, Bir İşçi

Süreç yöneticisinin ölçülecek iki ayarı var. Birincisi **yeniden başlatma politikası**: süreç
çıktığında ne kadar beklenip yeniden başlatılacağı ve kaç deneme sonra vazgeçileceği. İkincisi
**kaynak sınırı**: sürecin ne kadar bellek tutabileceği ve sınır aşıldığında ne yapılacağı. Üçüncü
bir ayar ikisinin dışında durur ve ikisinden de sessizdir: durdurma işaretinden sonra sürece
tanınan **bekleme süresi**.

- **DP1.** İşçi her açık ödünç kaydı için 2 MB ayırır ve tuttuğu toplamı yöneticiye bildirir; sınır
  bu bildirim üzerinden uygulanır. Gerçek dağıtımda aynı değer işletim sisteminden okunur.
- **DP2.** Bir isteğin işi sabit sürelidir. Bellek ölçümünde yanıtlar kabul sırasına göre 100
  milisaniye arayla verilir; sınırın hangi anda aşıldığı ve o anda kaç isteğin uçuşta olduğu böylece
  belirli olur.
- **DP3.** Bu derste tek bir işçi süreci vardır. Kopya sayısı sonraki dersin konusudur.

İşçi, ödünç uygulamasının çalışan hâlidir ve dört davranışı bir mod dizgesinden alır.

```js
// topoloji/isci.mjs — odunc isci sureci. Mod dizgesi davranisini belirler:
//   cok=<n>  n istek yanitladiktan sonra cikar   |  baslarken-cok=1  dinlemeden once cikar
//   is=<ms>  bir istegin suresi   basamak=<ms>  kabul sirasina gore isin uzamasi (yanitlar ayrisir)
//   bellek=yumusak  sinirda en eski kayitlarin yarisini atar ve ayakta kalir
//   kapanis=zarif|ani  durdurma isaretinde bekleyen istekleri bosaltir ya da hemen cikar
import { createServer } from "node:http";

const [nokta, modMetni] = [Number(process.argv[2]), process.argv[3] ?? ""];
const M = Object.fromEntries(modMetni.split(",").filter(Boolean).map((p) => p.split("=")));
const KAYIT_MB = 2;                       // tutulan odunc kaydi basina bellek
const SINIR_MB = 40;                      // yumusak sinir esigi
const tutulan = [];
let yanit = 0, atilan = 0, kabul = 0, kapaniyor = false;

if (Number.isInteger(nokta) === false) { console.log("kullanim: node topoloji/isci.mjs <nokta> <mod>"); process.exit(0); }
if (M["baslarken-cok"] === "1") process.exit(9);

const sunucu = createServer((istek, cevap) => {
  cevap.sendDate = false;
  if (kapaniyor) { cevap.writeHead(503).end("kapaniyor"); return; }
  const sira = kabul++;
  tutulan.push(new Array((KAYIT_MB * 1024 * 1024) / 8).fill(1));   // acik odunc kaydi bellekte durur
  if (M.bellek === "yumusak" && tutulan.length * KAYIT_MB > SINIR_MB) {
    atilan += tutulan.splice(0, tutulan.length >> 1).length;       // en eski yarisi atilir, surec yasar
  }
  setTimeout(() => {
    yanit += 1;
    cevap.writeHead(200, { "x-tutulan-mb": String(tutulan.length * KAYIT_MB) }).end("odunc");
    if (process.send !== undefined) process.send({ tutulanMB: tutulan.length * KAYIT_MB, yanit, atilan });
    if (M.cok !== undefined && yanit >= Number(M.cok)) process.exit(9);
  }, Number(M.is ?? 40) + sira * Number(M.basamak ?? 0));
});

process.on("SIGTERM", () => {
  if (M.kapanis === "zarif") { kapaniyor = true; sunucu.close(() => process.exit(0)); }
  else process.exit(0);                    // bekleyen istekler yaniti gormeden dusuyor
});
sunucu.listen(nokta, "127.0.0.1");
```

Yönetici işçiyi başlatır, bildirimlerini dinler, çıkışını yakalar ve politikayı uygular.

```js
// topoloji/yonetici.mjs — surec yoneticisi. Ayar dizgesi:
//   politika=aninda|geri-cekilmeli|sinirli:<n>   bellek=yok|sert:<mb>
//   sure=<ms>  0 ise durdurma isaretini bekler ve ozet basar; >0 ise o anda zarif durdurmayi baslatir
//   bekleme=<ms>  durdurma isaretinden sonra sert oldurmeye kadar taninan sure
import { fork } from "node:child_process";

const [nokta, ayarMetni, isciMod, etiket] = [process.argv[2], process.argv[3] ?? "", process.argv[4] ?? "", process.argv[5] ?? "-"];
const A = Object.fromEntries(ayarMetni.split(",").filter(Boolean).map((p) => p.split("=")));
const GERI = [100, 200, 400, 800, 1600];          // geri cekilme merdiveni (ms)
let deneme = 0, gecikme = 0, oldurme = 0, tepe = 0, atilan = 0, vazgecti = false, duruyor = false, cocuk = null;

function baslat() {
  let olduruldu = false;
  cocuk = fork("topoloji/isci.mjs", [nokta, isciMod], { stdio: ["ignore", "ignore", "ignore", "ipc"] });
  cocuk.on("message", (m) => {
    tepe = Math.max(tepe, m.tutulanMB);
    atilan = m.atilan;
    const sert = (A.bellek ?? "yok").startsWith("sert:") ? Number(A.bellek.split(":")[1]) : Infinity;
    if (m.tutulanMB > sert && olduruldu === false) {                   // sinir asildi: surec olduruluyor
      olduruldu = true;
      oldurme += 1;
      cocuk.kill("SIGKILL");
    }
  });
  cocuk.on("exit", () => { if (duruyor === false) yeniden(); });
}

function yeniden() {
  const en = (A.politika ?? "").startsWith("sinirli:") ? Number(A.politika.split(":")[1]) : Infinity;
  if (deneme >= en) { vazgecti = true; return; }
  const g = A.politika === "geri-cekilmeli" ? GERI[Math.min(deneme, GERI.length - 1)] : 0;
  deneme += 1;
  gecikme += g;
  setTimeout(baslat, g);
}

if (nokta === undefined) console.log("kullanim: node topoloji/yonetici.mjs <nokta> <ayar> <isci-mod> <etiket>");
else {
  setInterval(() => {}, 60000);          // vazgecildikten sonra da ozet icin ayakta kalinir
  baslat();
  process.on("SIGTERM", () => {
    duruyor = true;
    cocuk?.kill("SIGKILL");
    console.log(`${etiket} yonetici: ${deneme} yeniden baslatma, ${gecikme} ms gecikme, ${oldurme} oldurme, ` +
      `tepe ${tepe} MB, ${atilan} kayit atildi${vazgecti ? ", vazgecti" : ""}`);
    process.exit(0);
  });
  if (Number(A.sure ?? 0) > 0) setTimeout(() => {
    duruyor = true;
    cocuk.kill("SIGTERM");                                            // once zarif kapanma istegi
    const sert = setTimeout(() => cocuk.kill("SIGKILL"), Number(A.bekleme ?? 500));
    cocuk.on("exit", () => { clearTimeout(sert); process.exit(0); }); // bekleme dolmadan cikarsa temiz
  }, Number(A.sure));
}
```

Yük üreteci istekleri sabit aralıkla ya da hepsini birden gönderir ve üç sonucu ayırır: yanıtlanan,
temiz reddedilen, düşen.

```js
// topoloji/yuk.mjs — yuk ureteci. Kip "aralikli": adet istek, aralik ms arayla.
// Kip "esz": adet istek ayni anda. Baglanti kurulamayan ya da yanitsiz kapanan istek "dusen" sayilir.
import { request } from "node:http";

const [nokta, kip, adet, aralik, etiket] = [Number(process.argv[2]), process.argv[3], Number(process.argv[4]), Number(process.argv[5]), process.argv[6] ?? "-"];
const bekle = (ms) => new Promise((c) => setTimeout(c, ms));
let yanitlanan = 0, reddedilen = 0, dusen = 0;

const bir = () => new Promise((coz) => {
  const r = request({ port: nokta, path: "/odunc", agent: false }, (y) => {
    y.resume();
    y.on("end", () => { if (y.statusCode === 200) yanitlanan += 1; else reddedilen += 1; coz(); });
    y.on("aborted", () => { dusen += 1; coz(); });
  });
  r.on("error", () => { dusen += 1; coz(); });
  r.end();
});

if (Number.isInteger(nokta) === false) console.log("kullanim: node topoloji/yuk.mjs <nokta> <kip> <adet> <aralik> <etiket>");
else {
  if (kip === "esz") await Promise.all(Array.from({ length: adet }, bir));
  else {
    const acik = [];
    for (let i = 0; i < adet; i += 1) { acik.push(bir()); await bekle(aralik); }
    await Promise.all(acik);
  }
  console.log(`${etiket} yuk: ${adet} istek, ${yanitlanan} yanit, ${reddedilen} reddedilen, ${dusen} dusen`);
}
```

## Çöken Süreç ve Başlamayan Süreç

İlk düzenek aynı çökmeyi üç politikayla karşılıyor. İşçi her dört yanıttan sonra çıkıyor, yük 24
isteği 100 milisaniye arayla gönderiyor. Ardından aynı üç politika **hiç başlamayan** bir işçiyle
koşuyor: süreç dinlemeye geçmeden çıkıyor.

```bash
# olc1.sh — ayni cokme, uc yeniden baslatma politikasi. Isci her 4 yanittan sonra cikiyor.
kos() {                                   # kos <politika> <isci-mod> <adet> <etiket>
  node topoloji/yonetici.mjs 8941 "politika=$1,sure=0" "$2" "$4" & M=$!
  sleep 0.5
  node topoloji/yuk.mjs 8941 aralikli "$3" 100 "$4"
  kill -TERM $M; wait $M; sleep 0.2
}

kos aninda        "cok=4,is=40" 24 "cokme / aninda        "
kos geri-cekilmeli "cok=4,is=40" 24 "cokme / geri cekilmeli"
kos sinirli:2     "cok=4,is=40" 24 "cokme / sinirli (2)   "
kos aninda        "baslarken-cok=1" 8 "baslamiyor / aninda   "
kos geri-cekilmeli "baslarken-cok=1" 8 "baslamiyor / geri cek."
kos sinirli:2     "baslarken-cok=1" 8 "baslamiyor / sinirli 2"
```

```
cokme / aninda         yuk: 24 istek, 20 yanit, 0 reddedilen, 4 dusen
cokme / aninda         yonetici: 5 yeniden baslatma, 0 ms gecikme, 0 oldurme, tepe 8 MB, 0 kayit atildi
cokme / geri cekilmeli yuk: 24 istek, 14 yanit, 0 reddedilen, 10 dusen
cokme / geri cekilmeli yonetici: 3 yeniden baslatma, 700 ms gecikme, 0 oldurme, tepe 8 MB, 0 kayit atildi
cokme / sinirli (2)    yuk: 24 istek, 12 yanit, 0 reddedilen, 12 dusen
cokme / sinirli (2)    yonetici: 2 yeniden baslatma, 0 ms gecikme, 0 oldurme, tepe 8 MB, 0 kayit atildi, vazgecti
baslamiyor / aninda    yuk: 8 istek, 0 yanit, 0 reddedilen, 8 dusen
baslamiyor / aninda    yonetici: 43 yeniden baslatma, 0 ms gecikme, 0 oldurme, tepe 0 MB, 0 kayit atildi
baslamiyor / geri cek. yuk: 8 istek, 0 yanit, 0 reddedilen, 8 dusen
baslamiyor / geri cek. yonetici: 4 yeniden baslatma, 1500 ms gecikme, 0 oldurme, tepe 0 MB, 0 kayit atildi
baslamiyor / sinirli 2 yuk: 8 istek, 0 yanit, 0 reddedilen, 8 dusen
baslamiyor / sinirli 2 yonetici: 2 yeniden baslatma, 0 ms gecikme, 0 oldurme, tepe 0 MB, 0 kayit atildi, vazgecti
```

İlk üç ikili aynı çökmeyi karşılıyor ve sıralama beklenenin tersine dönüyor. **Anında** politikası
24 isteğin 20'sini yanıtladı, dördü düştü (bu koşumda). **Geri çekilmeli** politika 14 yanıt verdi,
on istek düştü — merdiven 100, 200 ve 400 milisaniyeyle toplam 700 milisaniyelik bir bekleme ekledi
ve o bekleme boyunca gelen her istek düştü. **Sınırlı** politika iki denemeden sonra vazgeçti ve
kalan on iki isteğin hepsi düştü; bu son sayı politikanın tanımından çıkar, koşumdan değil.

Yanıtlanan ve düşen sayılar sabit aralıklı bir yükten okunur ve makinenin o andaki yüküne bağlıdır;
koşumdan bağımsız olan, politikaların eklediği bekleme ile deneme sayılarıdır.

Çökme geçici olduğunda sıralama nettir: geri çekilme, bir sonraki denemenin başarılı olacağı
durumda saf kayıptır. Merdivenin varlık nedeni son üç satırda görünüyor.

İşçi hiç başlamadığında üç politika da aynı sonucu veriyor — sekiz isteğin sekizi düşüyor. Fark
istek tarafında değil, **makinenin harcadığı işte**: anında politikası aynı 0,8 saniyelik pencerede
onlarca süreç başlattı (bu koşumda 43), geri çekilmeli politika dört, sınırlı politika iki. Bu üç
sayının ikisi koşumdan bağımsızdır: geri çekilme merdiveni 100, 200, 400 ve 800 ile o pencereye dört
deneme sığdırır, sınırlı politika tanımı gereği ikide durur. Anında politikasının sayısı ise
pencere uzunluğu ile süreç başlatma maliyetinin oranıdır ve **üst sınırı yoktur**: pencere büyüdükçe
büyür, makine hızlandıkça büyür.

Bir ayrım daha var ve en sessiz olanı odur. Sınırlı politika **vazgeçti** diye yazıyor; öteki ikisi
sonsuza kadar denemeye devam eder. Ayakta olmayan bir sistem, hiç durmadan başlatılmaya çalışıldığı
sürece "başlatılıyor" görünür.

## Sınırı Aşmak: Öldürmek ve Yavaşlatmak

İkinci düzenek bellek sınırını iki yerde uyguluyor. **Sert** sınırda yönetici bildirimi okur ve
eşiği geçen süreci öldürür. **Yumuşak** sınırda işçi kendi eşiğini görür, en eski kayıtların yarısını
atar ve ayakta kalır. Yirmi dört istek birden gönderiliyor, yani sınır aşıldığında hepsi uçuşta.
Üçüncü düzenek durdurma işaretini uçuşta altı istek varken gönderiyor.

```bash
# olc2.sh — bellek siniri iki bicimde, ardindan durdurma isaretinde ucustaki istekler.
bellek() {                                # bellek <yonetici-ayar> <isci-mod> <etiket>
  node topoloji/yonetici.mjs 8942 "$1" "$2" "$3" & M=$!
  sleep 0.5
  node topoloji/yuk.mjs 8942 esz 24 0 "$3"
  kill -TERM $M; wait $M; sleep 0.2
}
bellek "politika=aninda,bellek=sert:40,sure=0" "is=200,basamak=100"                "sert sinir 40 MB "
bellek "politika=aninda,bellek=yok,sure=0"     "is=200,basamak=100,bellek=yumusak" "yumusak sinir 40 MB"

kapanis() {                               # kapanis <yonetici-ayar> <isci-mod> <etiket>
  node topoloji/yonetici.mjs 8943 "$1" "$2" "$3" & M=$!
  sleep 0.5
  node topoloji/yuk.mjs 8943 esz 6 0 "$3"
  wait $M; sleep 0.2
}
kapanis "politika=aninda,sure=700,bekleme=500" "is=300,kapanis=zarif" "zarif, bekleme 500 ms"
kapanis "politika=aninda,sure=700,bekleme=50"  "is=300,kapanis=zarif" "zarif, bekleme  50 ms"
kapanis "politika=aninda,sure=700,bekleme=500" "is=300,kapanis=ani"   "ani kapanma          "
```

```
sert sinir 40 MB  yuk: 24 istek, 1 yanit, 0 reddedilen, 23 dusen
sert sinir 40 MB  yonetici: 1 yeniden baslatma, 0 ms gecikme, 1 oldurme, tepe 48 MB, 0 kayit atildi
yumusak sinir 40 MB yuk: 24 istek, 24 yanit, 0 reddedilen, 0 dusen
yumusak sinir 40 MB yonetici: 0 yeniden baslatma, 0 ms gecikme, 0 oldurme, tepe 28 MB, 10 kayit atildi
zarif, bekleme 500 ms yuk: 6 istek, 6 yanit, 0 reddedilen, 0 dusen
zarif, bekleme  50 ms yuk: 6 istek, 0 yanit, 0 reddedilen, 6 dusen
ani kapanma           yuk: 6 istek, 0 yanit, 0 reddedilen, 6 dusen
```

Sert sınır 48 MB'de aşılıyor ve süreç öldürülüyor: yirmi dört isteğin **biri** yanıtlanıyor, yirmi
üçü düşüyor, bir yeniden başlatma yapılıyor. Yumuşak sınırda aynı yirmi dört isteğin yirmi dördü de
yanıtlanıyor, hiç düşen yok, hiç yeniden başlatma yok; bedel on kaydın atılması ve tepenin 48 yerine
28 MB'de kalmasıdır.

İki satır aynı eşiği aynı yükte karşılıyor ve **hangi işin kaybolduğu** değişiyor. Öldürmede
kaybolan şey uçuştaki isteklerdir: yirmi üç ödünç işlemi yarıda kesilir ve istemci yanıt almaz.
Kayıt atmada kaybolan şey bellekteki geçmiştir: süreç yaşar, istek yanıtlanır, atılan kaydın
gerektiğinde yeniden okunması gerekir. Birincisi görünür bir arıza üretir, ikincisi bir yavaşlama
üretir.

Yirmi üç sayısı sınırın aşıldığı anda uçuşta olan istek sayısıdır: öldürmenin faturası **o anda
taşınan işle** ölçülür.

Yumuşak sınırın sessiz tarafı da buradadır: hiçbir sayaç kırmızıya dönmez. Yirmi dört istek
yanıtlandı, düşen yok. Atılan kayıt sayısını raporlamayan bir düzenekte bu satır kusursuz görünür ve
bellek eşiğinin sürekli aşıldığı bilgisi hiçbir yere yazılmaz.

## Bekleme Süresi

Son üç satır durdurma işaretini uçuşta altı istek varken gönderiyor. İstek başına iş 300
milisaniye.

Zarif kapanmada işçi yeni istek almayı bırakır ve bekleyenleri boşaltır; bekleme 500 milisaniye
olduğunda altı isteğin **altısı** boşaltıldı. Aynı kod, bekleme 50 milisaniyeye çekildiğinde altı
isteğin **altısını** kaybetti: işçi boşaltmaya başladı, yönetici sonunu beklemedi ve süreci
öldürdü. Ani kapanmada işçi hiç boşaltmadı ve sonuç aynı oldu.

Üç satırın ikisi aynı sonucu veriyor, ama nedenleri farklı: birinde boşaltma **yok**, ötekinde
boşaltma **var ama tanınan süre yetmiyor**. Kod tarafında ikincisi doğru yazılmıştır; ayar tarafında
ikisi de aynı kadar kayıptır. Bekleme süresi, uygulamanın en uzun isteğinden büyük olmadıkça zarif
kapanma kodu çalışmaz — ve kodun çalışmadığı hiçbir yere yazılmaz.

## Ayarın Yeri

| Ayar | Yeri | Kaç yerde | Yanlış değerin sessiz sonucu |
|---|---|---|---|
| Yeniden başlatma politikası | süreç yöneticisi | 1 (her düğüm) | geçici çökmede fazladan düşen istek, kalıcı çökmede sonsuz başlatma döngüsü |
| Deneme sınırı | süreç yöneticisi | 1 | sınır yoksa arıza "başlatılıyor" olarak görünür |
| Bellek sınırı ve biçimi | yönetici (sert) ya da uygulama kodu (yumuşak) | 2 | öldürmede uçuştaki bütün istekler, kayıt atmada sessiz yavaşlama |
| Bekleme süresi | süreç yöneticisi | 1 | zarif kapanma kodu yazılıdır ve hiç çalışmaz |

Dört satırın üçü tek bir yerde durur ve tek bir sayıdır. Etkileri ancak bir çökme ya da bir yayın
sırasında görünür.

## Özet

- Aynı geçici çökmede anında yeniden başlatma 24 isteğin 20'sini yanıtladı, geri çekilmeli politika
  14'ünü, iki denemeyle sınırlı politika 12'sini (ilk ikisi bu koşumda); geri çekilmenin eklediği
  700 milisaniyelik bekleme doğrudan düşen isteğe dönüştü.
- Süreç hiç başlamadığında üç politika da sekiz isteğin sekizini kaybetti; fark harcanan işte oldu —
  anında politikası aynı pencerede onlarca süreç başlattı (bu koşumda 43), geri çekilmeli dört,
  sınırlı iki, ve yalnız sonuncusu vazgeçtiğini bildirdi.
- Geri çekilme merdiveninin ve deneme sınırının ürettiği sayılar koşumdan bağımsızdır; anında
  politikasının başlatma sayısının üst sınırı yoktur.
- Bellek sınırı sert uygulandığında yirmi dört isteğin yirmi üçü düştü ve bir yeniden başlatma
  yapıldı; yumuşak uygulandığında hiç istek düşmedi ve bedel on kaydın atılması oldu. Düşen istek
  sayısı, sınırın aşıldığı anda uçuşta olan iş kadardır.
- Zarif kapanmada 500 milisaniyelik bekleme uçuştaki altı isteğin altısını boşalttı; aynı kod 50
  milisaniyelik beklemeyle altısını da kaybetti ve sonuç ani kapanmayla aynı çıktı.

## Sonraki Adım

Bu iki ders tek bir süreçle çalıştı. Vekil tek bir hedefe iletti, yönetici tek bir işçiyi
başlattı ve bellek sınırı o tek sürecin sınırıydı. Yükü karşılamanın iki yolu vardır ve ikisi de
bu tek sayıya dokunur: sürece daha çok kaynak vermek ya da daha çok süreç açmak. İki yol aynı
isteği karşılar, aynı yanıtı döndürür ve arka planda birbirinden çok farklı bir fatura üretir.
Sonraki ders aynı yükü tek büyük süreçle ve dört küçük süreçle karşılar; bellek toplamını, ayağa
kalkma süresini ve her sürecin kendi bağlantı havuzunu açmasından doğan çarpanı ölçer — bir
sürecin havuz ayarı doğruyken dört sürecin aynı ayarı depoya dört katı bağlantı gönderir.
