---
title: 'Sağlık Uçları'
source: 'https://academia.sh/tr/kurslar/gozlemlenebilirlik/saglik-uclari'
course: 'Gözlemlenebilirlik ve Güvenilirlik'
language: tr
updated: '2026-08-17T18:06:52+00:00'
license: 'CC BY-SA 4.0'
---

# Sağlık Uçları

Canlılık ile hazır olmanın kodda ayrı tutulması: iki ucun hangi soruyu yanıtladığı, bağımlılık denetiminin canlılık ucuna girmesinin ürettiği yeniden başlatma döngüsü ve aynı senaryonun iki kipte koşularak düşen istek ile toparlanma süresinin sayılması.

Önceki derste kurulan her kural bir insanı çağırıyor ve insan dakikalar içinde yanıt veriyor. Bazı
kararlar ise insana hiç sorulmaz. Ödünç sisteminin süreçlerinden birinin yaşayıp yaşamadığına ve
trafik alıp almayacağına makine karar verir, saniyeler içinde ve günde binlerce kez. Bu karar iki
ayrı soruya bakar; iki soru tek bir uca bağlandığında verilen yanıt yalnız yanlış olmaz, kendini
besleyen bir döngü kurar.

Dayanıklılık ve Güvenilirlik kursu sağlık ucunun içeriğini ve denetim aralığını ölçtü; o tarama
burada tekrarlanmaz. Buradaki soru tek: iki uç kodda ayrı mı, ve ayrılmadığında ne oluyor.

## İki Soru, İki Eylem

**Canlılık** ucunun sorusu şudur: bu süreç ölmüş mü, ve yeniden başlatmak durumu düzeltir mi.
Yanıtı olumsuzsa denetleyici tek bir eylem yapar — süreci öldürüp yeniden başlatır.

**Hazır olma** ucunun sorusu başkadır: bu süreç şu an iş alabilir mi. Yanıtı olumsuzsa eylem
başkadır — trafik kesilir, ama süreç yaşamaya devam eder ve kendi kendine toparlanması beklenir.

Ayrımın kuralı bu iki eylemden çıkar: **bir denetimin canlılık ucuna girebilmesi için, o denetim
başarısız olduğunda yeniden başlatmanın çözüm olması gerekir.** Sürecin kendi kilidi, kendi belleği,
kendi olay döngüsü bu ölçüte uyar; süreç yeniden doğduğunda temizlenirler. Bir bağımlılık uymaz.
Üyelik servisi erişilemezken ödünç sürecini yeniden başlatmak üyelik servisini geri getirmez;
denetim yeni süreçte de başarısız olur, denetleyici onu da öldürür ve döngü bağımlılık dönene kadar
sürer.

## Düğüm: Ayrım İki Satırdadır

```js
// saglik/dugum.mjs — odunc dugumu: iki saglik ucu (/canlilik, /hazir) ve iki is ucu.
// Kip "ayri" ise canlilik yalniz surecin kendi durumunu okur; kip "birlesik" ise canlilik
// uyelik servisine olan bagimliligi da denetler. Ayrimin tamami su iki satirdadir.
import { createServer } from "node:http";
import { readFileSync } from "node:fs";
// SD1 (varsayim): yeniden baslayan surec yerel dizinini 24 istek boyunca yeniden kurar.
export const ISINMA = 24;

export function baslat(kip) {
  let islenen = 0, kilitli = false;
  const bagimli = () => readFileSync("bagimlilik.durum", "utf8").trim() === "acik";
  const s = createServer((istek, yanit) => {
    let kod = 200;
    if (istek.url === "/canlilik") kod = kilitli || (kip === "birlesik" && !bagimli()) ? 500 : 200;
    else if (istek.url === "/hazir") kod = bagimli() && islenen >= ISINMA ? 200 : 503;
    else {
      islenen += 1;
      if (islenen <= ISINMA) kod = 503;                          // yerel dizin henuz kurulmadi
      else if (istek.url === "/odunc" && !bagimli()) kod = 503;   // uyelik servisi gerekli
    }
    yanit.writeHead(kod).end();
  });
  s.listen(0, "127.0.0.1", () => process.send({ port: s.address().port }));
}

if (process.argv[2]) baslat(process.argv[2]);
else console.log(`uclar: /canlilik /hazir /ara /odunc; isinma ${ISINMA} istek; ` +
  `/ara bagimlilik gerektirmez, /odunc gerektirir`);
```

```
uclar: /canlilik /hazir /ara /odunc; isinma 24 istek; /ara bagimlilik gerektirmez, /odunc gerektirir
```

İki uç arasındaki bütün fark `bagimli()` çağrısının hangi satırda geçtiğidir. Hazır olma ucunda
geçer, çünkü bağımlılık yoksa süreç iş alamaz. Canlılık ucunda geçmemelidir; `birlesik` kipi tam
olarak bu hatayı yapar ve tek bir koşul terimi ekler. Süreç iki iş ucu sunar: `/ara` yerel dizinden
yanıt verir ve üyelik servisine ihtiyaç duymaz, `/odunc` duyar. Yeniden başlayan süreç yerel dizini
kaybeder ve yirmi dört istek boyunca ikisine de yanıt veremez.

## Aynı Senaryo, İki Kip

```js
// saglik/denetleyici.mjs — ayni senaryo iki kipte kosulur: uyelik servisi 15. tikte kapanir,
// 40. tikte acilir. Denetleyici her 2 tikte canlilik ve hazir olma ucunu yoklar, 3 ardisik
// canlilik hatasinda sureci yeniden baslatir. Her tikte 2 arama ve 2 odunc istegi gonderilir.
import { fork } from "node:child_process";
import { writeFileSync } from "node:fs";
import { request } from "node:http";
// SD2 (varsayim): denetim araligi 2 tik, yeniden baslatma esigi 3 ardisik canlilik hatasi.
const TIK = 60, KAPALI = [15, 40], DENETIM = 2, ESIK = 3, ISINMA = 24;

const cagir = (port, yol) => new Promise((c) => {
  const r = request({ host: "127.0.0.1", port, path: yol }, (y) => { y.resume(); c(y.statusCode); });
  r.on("error", () => c(0));
  r.end();
});
const ac = (kip) => new Promise((c) => {
  const p = fork(new URL("dugum.mjs", import.meta.url), [kip],
    { stdio: ["ignore", "ignore", "ignore", "ipc"] });
  p.once("message", (m) => c([p, m.port]));
});

async function kosum(kip) {
  writeFileSync("bagimlilik.durum", "acik");
  let [p, port] = await ac(kip);
  for (let i = 0; i < ISINMA; i += 1) await cagir(port, "/ara");   // ilk isinma sayilmaz
  const s = { yeniden: 0, ara: 0, odunc: 0, hazirDegil: 0, toparlanma: -1 };
  let ardisik = 0;
  for (let t = 0; t < TIK; t += 1) {
    writeFileSync("bagimlilik.durum", t >= KAPALI[0] && t < KAPALI[1] ? "kapali" : "acik");
    if (t % DENETIM === 0) {
      ardisik = (await cagir(port, "/canlilik")) === 200 ? 0 : ardisik + 1;
      if (ardisik >= ESIK) {
        ardisik = 0; s.yeniden += 1;
        p.kill(); await new Promise((c) => p.once("exit", c));
        [p, port] = await ac(kip);
      }
      if ((await cagir(port, "/hazir")) !== 200) s.hazirDegil += 1;
    }
    let iyi = 0;
    for (const yol of ["/ara", "/ara", "/odunc", "/odunc"]) {
      if ((await cagir(port, yol)) === 200) iyi += 1;
      else if (yol === "/ara") s.ara += 1; else s.odunc += 1;
    }
    if (t >= KAPALI[1] && iyi === 4 && s.toparlanma < 0) s.toparlanma = t - KAPALI[1];
  }
  p.kill();
  return s;
}

const cikti = [];
for (const kip of ["ayri", "birlesik"]) cikti.push([kip, await kosum(kip)]);
console.log(`${TIK} tik, tik basina 4 istek; uyelik servisi ${KAPALI[0]}.-${KAPALI[1]}. tikler ` +
  `arasinda kapali (${KAPALI[1] - KAPALI[0]} tik), isinma ${ISINMA} istek`);
console.log(`\n${"kip".padEnd(10)}${"yeniden baslatma".padStart(18)}${"dusen /ara".padStart(12)}` +
  `${"dusen /odunc".padStart(14)}${"hazir degil".padStart(13)}${"toparlanma".padStart(12)}`);
for (const [kip, s] of cikti)
  console.log(`${kip.padEnd(10)}${String(s.yeniden).padStart(18)}${String(s.ara).padStart(12)}` +
    `${String(s.odunc).padStart(14)}${(s.hazirDegil + " yoklama").padStart(13)}` +
    `${(s.toparlanma + " tik").padStart(12)}`);
const [a, b] = cikti.map(([, s]) => s);
console.log(`\nbirlesik kipte dusen ${b.ara} arama istegi uyelik servisine hic ihtiyac duymuyordu; ` +
  `ayri kipte bu sayi ${a.ara}`);
console.log(`toplam dusen istek: ayri ${a.ara + a.odunc}, birlesik ${b.ara + b.odunc} ` +
  `(${b.ara + b.odunc - a.ara - a.odunc} istek yalnizca yanlis siniflandirmadan)`);
```

```
60 tik, tik basina 4 istek; uyelik servisi 15.-40. tikler arasinda kapali (25 tik), isinma 24 istek

kip         yeniden baslatma  dusen /ara  dusen /odunc  hazir degil  toparlanma
ayri                       0           0            50   12 yoklama       0 tik
birlesik                   4          48            58   14 yoklama       4 tik

birlesik kipte dusen 48 arama istegi uyelik servisine hic ihtiyac duymuyordu; ayri kipte bu sayi 0
toplam dusen istek: ayri 50, birlesik 106 (56 istek yalnizca yanlis siniflandirmadan)
```

## Yanlış Sınıflandırmanın Bedeli

`ayri` kipinde yeniden başlatma yok. Üyelik servisi yirmi beş tik boyunca kapalıyken hazır olma ucu
on iki yoklamada olumsuz yanıt verdi — yani trafik yönlendiricisi bu düğümü listeden çıkarabilirdi —
ama süreç yaşadı. Düşen 50 istek yalnız `/odunc` isteğidir: bunlar zaten üyelik servisi olmadan
yapılamayacak işlerdi. Arama isteklerinin hiçbiri düşmedi. Bağımlılık 40. tikte döndüğünde
toparlanma **aynı tikte** oldu, çünkü süreç bellekteki dizinini hiç kaybetmemişti.

`birlesik` kipinde canlılık ucu bağımlılığa bakınca zincir kuruldu. Üç ardışık olumsuz yoklamadan
sonra denetleyici süreci öldürdü, yeni süreç aynı bağımlılığı bulamadığı için o da öldürüldü:
kapalı geçen yirmi beş tikte **dört yeniden başlatma**. Her yeniden başlatma yerel dizini sıfırladı
ve yirmi dört istek boyunca `/ara` da yanıt veremedi. Sonuç: 48 arama isteği düştü, oysa bu
isteklerin üyelik servisine hiç ihtiyacı yoktu. `/odunc` düşüşü de 50'den 58'e çıktı, çünkü
bağımlılık döndükten sonra süreç hâlâ ısınıyordu.

İki sayı bu dersin ölçüsüdür. **Toplam düşen istek 50'den 106'ya çıktı; 56 istek yalnızca yanlış
sınıflandırma yüzünden düştü.** Ve toparlanma süresi 0 tikten 4 tike çıktı: bağımlılık geri
geldikten sonra bile sistem, son yeniden başlatmanın ısınma borcunu ödeyene kadar yanıt veremedi.
Bu ikinci sayı döngünün asıl niteliğini gösteriyor — yeniden başlatma arızayı uzatır, kısaltmaz.

## Ayrımı Kodda Korumak

İki ucun tek bir yardımcı işleve indirgenmesi en sık yapılan hatadır: `saglikDurumu()` adında bir
işlev yazılır, bütün denetimleri koşar ve iki uç da onu çağırır. Bu yazımda ayrım bir gün sonra
kaybolur, çünkü yeni bir bağımlılık denetimi eklemek isteyen kişi tek bir yere ekler ve o yer her
iki uca birden bağlıdır. Yukarıdaki düğümde iki uç ayrı satırlardır ve aralarında paylaşılan tek
şey `bagimli()` okuyucusudur; hangi ucun onu çağıracağı her seferinde açıkça yazılır.

Karar için üç maddelik bir ölçüt yeter. Sürecin kendi durumu — kilit, bellek, olay döngüsü —
canlılığa girer, çünkü yeniden başlatmak onları düzeltir. Bağımlılıklar ve ısınma hazır olmaya
girer, çünkü beklemek düzeltir, öldürmek düzeltmez. Tükenen kaynaklar — disk, bağlantı sayısı —
hiçbirine girmez; onlar önceki dersin uyarı kuralına aittir, çünkü ne yeniden başlatma ne trafik
kesme onları çözer.

## Özet

- Canlılık "bu süreç ölmüş mü" sorusunu yanıtlar ve yeniden başlatmayı tetikler; hazır olma "şu an
  iş alabilir mi" sorusunu yanıtlar ve yalnız trafiği keser.
- Bir denetim canlılık ucuna ancak başarısızlığında yeniden başlatmak çözümse girer; bağımlılık
  denetimi bu ölçüte uymaz.
- Aynı yirmi beş tiklik bağımlılık kesintisinde ayrı tutulan uçlar sıfır yeniden başlatma üretti,
  birleşik uç dört yeniden başlatma üretti.
- Yanlış sınıflandırma, bağımlılığa hiç ihtiyacı olmayan 48 arama isteğini düşürdü; toplam düşen
  istek 50'den 106'ya çıktı ve 56 istek yalnızca bu hatadan kaynaklandı.
- Yeniden başlatma arızayı uzattı: bağımlılık döndükten sonra toparlanma 0 tik yerine 4 tik sürdü,
  çünkü her yeniden başlatma yerel dizini sıfırladı.
- Ayrım kodda tek bir koşul terimidir ve iki ucu ortak bir `saglikDurumu()` işlevine indirgemek onu
  ilk eklemede kaybettirir.

## Sonraki Adım

Bu konu telemetriyi karara çevirdi: gösterge tanımlandı, dört sinyal hesaplandı, hedefin tersi
harcanabilir bir bütçeye dönüştü, uyarı kuralı belirtiden yazıldı ve iki sağlık ucu ayrıldı. Artık
bir sınırın aşıldığı **söylenebiliyor.** Söylenmesiyle birlikte değişen bir şey ise yok. Üyelik
servisi kapalıyken ödünç düğümü aynı isteği aynı biçimde göndermeye, aynı süre boyunca beklemeye ve
aynı hatayı almaya devam etti; hazır olma ucu bunu bildirdi ama isteği durduran, kısaltan ya da
başka bir yola çeviren hiçbir kod yoktu. Ölçmek gözlemi değiştirir, davranışı değiştirmez. Sonraki
konu davranışı değiştiren kalıpları kodun içine yerleştirir ve her birinin hangi katmanda durduğunu,
kaç çağrı yerini sardığını ve hangi çağrı yerini atladığını sayar.
