Ders 02 / 15
Servis Keşfi
Kopya adreslerinin elle yazılan bir listeden çıkarılıp kayıt defterine taşınması: servis keşfinin yük dengeleyicinin sağlık denetiminden ayrılması, kayıt yaşam süresi ile çözümleme önbelleğinin bir arızayı fark etme penceresini ne kadar uzattığının modelle ölçülmesi, zarif kapanmanın pencereyi sıfırlaması ve pencerenin giriş kursundaki kesinti bütçesine çevrilmesi.
İçindekiler
Önceki ders kopyaları birbirinin eşi hâline getirdi: durum süreç dışına taşındı, yük serbestçe bölünebilir oldu ve gereken kopya sayısı 3’e indi. Ama ölçüm düzeneğinin bir parçası hâlâ el yazısıyla duruyordu — sürücü betik kopyaların bağlantı noktalarını komut satırından aldı, istemci aynı sayıları elle taşıdı. Trafik Katmanı kursunun yük dengeleyicisi de kopya listesini aynı biçimde almıştı. Kopya sayısı değiştiğinde, bir kopya düştüğünde ya da yeni bir kopya ayağa kalktığında bu listeyi kimin güncellediği hiçbir yerde yazılı değil.
Servis keşfi (service discovery), bir servisin o anda ayakta olan kopyalarının adreslerinin çalışma zamanında bulunmasıdır. Yük dengeleyiciyle karıştırılmaya açıktır ve ikisi ayrı işler yapar: dengeleyici isteği dağıtır, keşif adresi bulur. Dengeleyicinin havuzu, keşfin ürettiği listedir; keşif olmadan o liste bir yapılandırma dosyasında durur. Bu ders listenin nereden geldiğini, güncellenmesinin ne kadar sürdüğünü ve o sürede kaç isteğin ölü bir adrese gittiğini ölçer.
İki Yerleşim
Statik liste. Adresler her çağıran servisin yapılandırmasında yazılıdır. Bir kopya düştüğünde hiçbir çağıran bunu kendiliğinden fark etmez; liste değiştiğinde her çağıranın yapılandırması ayrı ayrı güncellenir.
Kayıt defteri. Kopyalar ayağa kalkınca kendilerini bir kayıt defterine yazar ve düzenli aralıklarla kalp atışı (heartbeat) gönderir. Kaydın bir yaşam süresi vardır; kalp atışı kesildiğinde kayıt bu süre dolunca düşer. Çağıran adresi çağrı anında defterden çözer.
İki yerleşimde de bir gecikme vardır ve dersin ölçtüğü sayı odur: bir kopya susmasıyla listeden düşmesi arasında geçen fark etme penceresi.
Model
Aşağıdaki düzenek bir modeldir: kayıt defteri, kalp atışı ve çözümleme birer modüldür, süreler mantıksal saatle ilerler, arıza ve yeni kopya birer parametreyle tetiklenir. Gerçek bir keşif altyapısı, hizmet ağı ürünü ya da bulut ortamı kurulmaz. Modelin iki sayısı bu kursun varsayımıdır ve K01’in tablosuna eklenmez.
U2 — kalp atışı aralığı 1000 ms, kayıt yaşam süresi 3000 ms. Gerekçe: yaşam süresi, tek bir kayıp kalp atışının kaydı düşürmemesi için aralığın birkaç katı seçilir; burada üç katı alındı. Duyarlılığı aşağıda hesaplandı.
// kesif/defter.mjs — kayit defteri MODELI: kayit, kalp atisi, yasam suresi ve zarif kapanma. // Sure gercek degil, mantiksal saattir (ms); ariza ve yeni kopya parametreyle tetiklenir. export const KALP = 1000; // varsayim U2: kalp atisi araligi (ms) export const YASAM = 3000; // varsayim U2: kaydin yasam suresi (ms) export function defter() { const kayit = new Map(); return { kalpAtisi: (ad, adres, t) => kayit.set(adres, { ad, son: t }), kaydiSil: (adres) => kayit.delete(adres), coz: (ad, t) => [...kayit.entries()] .filter(([, k]) => k.ad === ad && t - k.son < YASAM) .map(([adres]) => adres), }; } // Cozumleme onbellegi: cagiran cozdugu listeyi sure kadar elinde tutar. export function cozucu(d, ad, onbellekMs) { let liste = [], tazeleme = -Infinity; return (t) => { if (t - tazeleme >= onbellekMs) { liste = d.coz(ad, t); tazeleme = t; } return liste; }; }
Koşum aynı arızayı dört yerleşimde tekrarlar. k2 kopyası beşinci saniyede susar, k4 kopyası
altıncı saniyede ayağa kalkar; çağıran on milisaniyede bir istek gönderir ve listeden sırayla bir
adres seçer.
// kesif/olc.mjs — ayni arizada dort yerlesim: statik liste, kayit defteri, cozumleme onbellegi, zarif kapanma import { defter, cozucu, KALP, YASAM } from "./defter.mjs"; const KOPYA = ["k1", "k2", "k3"]; // baslangicta ayakta olan kopyalar const ARIZA = 5000; // k2 bu anda susuyor (model parametresi) const YENI = 6000; // k4 bu anda ayaga kalkiyor (model parametresi) const BAS = 5000, BIT = 11000, ADIM = 10; // istek penceresi ve istek araligi (ms) const TUKETICI = 4; // cagiran servis sayisi: gecit, ucretlendirme, teslimat-op, toplu isci function kosum({ onbellek = 0, zarifKapanma = false, statik = false }) { const d = defter(); const coz = cozucu(d, "takip", onbellek); let sira = 0, dusen = 0, yeniyeGiden = 0, sonDusen = null, sondaListede = false; for (let t = 0; t <= BIT; t += ADIM) { for (const k of KOPYA) { // kalp atislari if (t % KALP === 0 && (k !== "k2" || t <= ARIZA)) d.kalpAtisi("takip", k, t); } if (t % KALP === 0 && t >= YENI) d.kalpAtisi("takip", "k4", t); if (zarifKapanma && t === ARIZA) d.kaydiSil("k2"); if (t < BAS) continue; const liste = statik ? [...KOPYA] : coz(t); // statik liste arizadan haberdar olmaz sondaListede = liste.includes("k2"); const secilen = liste[sira++ % liste.length]; if (secilen === "k2") { dusen += 1; sonDusen = t; } if (secilen === "k4") yeniyeGiden += 1; } const pencere = sondaListede ? "elle" : sonDusen === null ? "0" : String(sonDusen - ARIZA + ADIM); return { dusen, yeniyeGiden, pencere }; } const YERLESIM = [ ["statik liste", { statik: true }, TUKETICI], ["kayit defteri", {}, 1], ["defter + onbellek 800", { onbellek: 800 }, 1], ["defter + zarif kapanma", { zarifKapanma: true }, 1], ]; console.log(`kalp atisi ${KALP} ms, yasam suresi ${YASAM} ms; k2 ${ARIZA} ms'de susuyor, ` + `k4 ${YENI} ms'de kaydoluyor`); console.log(`istek penceresi ${BAS}-${BIT} ms, ${ADIM} ms'de bir istek = ${(BIT - BAS) / ADIM + 1} istek\n`); console.log(`${"yerlesim".padEnd(26)}${"fark etme penceresi(ms)".padStart(24)}` + `${"olu adrese giden".padStart(18)}${"yeni kopyaya giden".padStart(20)}${"yapilandirma noktasi".padStart(22)}`); for (const [ad, secenek, nokta] of YERLESIM) { const r = kosum(secenek); console.log(`${ad.padEnd(26)}${r.pencere.padStart(24)}${String(r.dusen).padStart(18)}` + `${String(r.yeniyeGiden).padStart(20)}${String(nokta).padStart(22)}`); }
kalp atisi 1000 ms, yasam suresi 3000 ms; k2 5000 ms'de susuyor, k4 6000 ms'de kaydoluyor istek penceresi 5000-11000 ms, 10 ms'de bir istek = 601 istek yerlesim fark etme penceresi(ms) olu adrese giden yeni kopyaya giden yapilandirma noktasi statik liste elle 200 0 4 kayit defteri 2980 83 150 1 defter + onbellek 800 3180 93 134 1 defter + zarif kapanma 0 0 167 1
Ölçülen Etki
Bu sayılar modelden çıkar ve belirlenimlidir: mantıksal saat ve sabit istek aralığı aynı sonucu her koşumda verir.
Statik liste hiç fark etmiyor. Ölü adrese 601 isteğin 200’ü gidiyor ve pencere kapanmıyor;
kapanması için bir kişinin dört ayrı yapılandırmayı değiştirmesi gerekir. yeni kopyaya giden
sütunu ikinci yarıyı veriyor: k4 ayağa kalktı ve statik düzende hiç istek almadı. Ölçek
artışının yararı da aynı gecikmeyle bekliyor.
Kayıt defteri pencereyi kapatıyor ama anında değil. Pencere 2980 milisaniye, yani yaşam
süresinin neredeyse tamamı. Sekseniki isteğin ölü adrese gitmesi bir kusur değil, seçilen yaşam
süresinin doğrudan sonucudur: kayıt, kalp atışı kesildikten sonra üç saniye daha listede durur.
k4 bu düzende 150 istek alıyor — kayıt defteri yalnız düşeni çıkarmakla kalmıyor, yeni geleni
de tanıtıyor.
Çözümleme önbelleği pencereyi uzatıyor. Çağıran listeyi 800 milisaniye elinde tuttuğunda pencere 2980’den 3180’e, ölü adrese giden istek 83’ten 93’e çıkıyor. Önbellek defterin yükünü düşürür ve bunu pencereyi büyüterek yapar; iki sayı aynı kararın iki yüzüdür.
Zarif kapanma pencereyi sıfırlıyor. Kopya kapanmadan önce kaydını kendisi siliyor ve ölü adrese hiç istek gitmiyor. Bu satır önemlidir çünkü kopyaların çoğu planlı olarak kapanır — yayın, ölçek küçültme, taşınma. Planlı kapanmalarda pencereyi ödemek gerekmiyor; yaşam süresi yalnız plansız susmalar için bir sigortadır.
Son sütun ayrı bir ölçüdür: yapılandırma noktası statik düzende 4, defterle 1. Sayı çağıran servis sayısıyla büyür; kopya listesinin her tüketicide tekrarlanması, kopya sayısı değiştiğinde yapılacak işin tüketici sayısıyla çarpılması demektir.
Hesaba Geri Dönüş
Pencere bir süredir ve K01 ile K02’nin sayıları onu isteğe çevirir. Trafik Katmanı kursu aynı hesabı sağlık denetimi için yapmış, arıza başına 34,26 istek bulmuştu.
// kesif/butce.mjs — fark etme penceresinin K01 istek hizi ve kesinti butcesindeki karsiligi const TEPE_UC = 513.89; // K01 Kabaca Buyukluk Hesabi: tepe ucta istek/s const KOPYA = 3; // K02 Yuk Dengeleyici Rolu: en az kopya sayisi const ARIZA_AY = 2.82; // K01 Erisilebilirligin Sayisal Ifadesi: ayda butceye sigan ariza const AY_ISTEK = (12_000_000 + 2_800_000) * 30; // K01: gunluk takip sorgusu + durum olayi const SAGLIK = 0.2, DEFTER = 2.98; // K02 varsayim Y3 penceresi ve modelin olctugu pencere const PENCERE = [ ["saglik denetimi (K02 Y3)", SAGLIK], ["kayit defteri (U2)", DEFTER], ["defter + onbellek 800", 3.18], ["zarif kapanma", 0], ["elle mudahale (K01)", 600], ]; const payHiz = TEPE_UC / KOPYA; console.log(`kopya basina hiz = ${TEPE_UC} / ${KOPYA} = ${payHiz.toFixed(2)} istek/s\n`); console.log(`${"pencere kaynagi".padEnd(26)}${"sn".padStart(7)}${"ariza basina dusen".padStart(20)}` + `${"aylik dusen".padStart(13)}${"istek tabanli erisilebilirlik".padStart(31)}`); for (const [ad, sn] of PENCERE) { const bir = payHiz * sn, aylik = bir * ARIZA_AY; console.log(`${ad.padEnd(26)}${String(sn).padStart(7)}${bir.toFixed(2).padStart(20)}` + `${aylik.toFixed(0).padStart(13)}${`%${(100 * (1 - aylik / AY_ISTEK)).toFixed(5)}`.padStart(31)}`); } console.log(`\nikisi birlikte: etkin pencere = min(${SAGLIK}, ${DEFTER}) = ${Math.min(SAGLIK, DEFTER)} sn ` + `-> ${(payHiz * Math.min(SAGLIK, DEFTER)).toFixed(2)} istek; kesif tek basina ${(DEFTER / SAGLIK).toFixed(1)} kat kotu`); const kalp = (yasam) => (KOPYA * 1000) / (yasam / 3); console.log(`duyarlilik: U2'nin yasam suresi 3000 -> 1000 ms olsaydi pencere ${(DEFTER - 2).toFixed(2)} sn, ` + `ariza basina ${(payHiz * (DEFTER - 2)).toFixed(2)} istek`); console.log(` defterin kendi yuku ${kalp(3000).toFixed(2)} -> ${kalp(1000).toFixed(2)} atis/s ` + `(K02'nin saglik denetimi yuku 15 istek/s)`);
kopya basina hiz = 513.89 / 3 = 171.30 istek/s pencere kaynagi sn ariza basina dusen aylik dusen istek tabanli erisilebilirlik saglik denetimi (K02 Y3) 0.2 34.26 97 %99.99998 kayit defteri (U2) 2.98 510.46 1440 %99.99968 defter + onbellek 800 3.18 544.72 1536 %99.99965 zarif kapanma 0 0.00 0 %100.00000 elle mudahale (K01) 600 102778.00 289834 %99.93472 ikisi birlikte: etkin pencere = min(0.2, 2.98) = 0.2 sn -> 34.26 istek; kesif tek basina 14.9 kat kotu duyarlilik: U2'nin yasam suresi 3000 -> 1000 ms olsaydi pencere 0.98 sn, ariza basina 167.87 istek defterin kendi yuku 3.00 -> 9.00 atis/s (K02'nin saglik denetimi yuku 15 istek/s)
Bu sayılar hesap sınıfındadır. Tablo bir sıralama veriyor: sağlık denetimi 34,26, kayıt defteri 510,46, elle müdahale 102.778 istek. Keşif, elle tutulan listeye göre iki yüz kat iyi, sağlık denetimine göre on beş kat kötü. Bu iki karşılaştırma birlikte okunmalıdır, çünkü dersin asıl savı buradadır: servis keşfi bir arıza algılama aracı değildir. İşi, listenin doğru kaynaktan gelmesini sağlamaktır; arızayı hızlı fark etme işi hâlâ sağlık denetiminindir.
İkisi birlikte kullanıldığında etkin pencere küçük olanla belirlenir. Dengeleyici düşen kopyayı 200 milisaniyede havuzundan çıkarır; defterin kaydı üç saniye daha durur ama o kayıt zaten dengeleyicinin havuzuna girmez. Bir katman diğerinin yerine geçmiyor, biri ötekinin girdisini üretiyor.
Duyarlılık satırı U2’nin fiyatını gösteriyor. Yaşam süresi 3000 milisaniyeden 1000’e indirilirse pencere 0,98 saniyeye ve arıza başına düşen istek 167,87’ye iner, ama kalp atışı aralığı da üçte birine inmek zorundadır: defterin kendi yükü 3,00 atıştan 9,00 atış/s’ye çıkar. Karşılaştırma noktası K02’nin sağlık denetimi yüküdür — 15 istek/s. Keşif katmanının gözlem yükü, sağlık denetiminin yükünün altındadır ve pencereyi kısaltmak onu doğrusal büyütür.
Özet
- Servis keşfi ile yük dengeleme ayrı işlerdir: dengeleyici isteği dağıtır, keşif adresi bulur; keşfin ürettiği liste dengeleyicinin havuzudur.
- Statik listede ölü adrese 601 isteğin 200’ü gitti ve pencere kendiliğinden kapanmadı; yeni ayağa kalkan kopya hiç istek almadı ve yapılandırma noktası tüketici sayısı kadar (4) oldu.
- Kayıt defterinde pencere 2980 ms, ölü adrese giden 83 istek; yeni kopya 150 istek aldı ve yapılandırma noktası 1’e indi.
- Çözümleme önbelleği defterin yükünü düşürürken pencereyi 3180 ms’ye ve düşen isteği 93’e çıkarıyor; zarif kapanma pencereyi 0’a indiriyor, çünkü kopya kaydını kendisi siliyor.
- K01’e dönüş: arıza başına düşen istek sağlık denetiminde 34,26, kayıt defterinde 510,46, elle müdahalede 102.778; keşif elle tutulan listeye göre iki yüz kat iyi, sağlık denetimine göre on beş kat kötüdür.
- U2 duyarlılığı: yaşam süresi 1000 ms’ye inerse pencere 0,98 saniyeye düşer, defterin kendi yükü 3,00’ten 9,00 atış/s’ye çıkar (K02’nin sağlık denetimi yükü 15 istek/s).
Sonraki Adım
Adres artık çalışma zamanında bulunuyor ve liste kendini güncelliyor. Bu, iki servisin birbirine ulaşabilmesi için gereken son parçaydı; ama ulaştıktan sonra ne konuşacakları seçilmedi. Ağ geçidi teslimat operasyonu ile ücretlendirme servisini paralel çağırıp yanıtlarını birleştiriyordu ve o çağrıların biçimi hiçbir yerde tartışılmadı. Sonraki ders o seçimi ele alır: aynı iç çağrı üç ayrı biçimde yazılır ve üç ölçüyle karşılaştırılır — bir dış istek için yapılan iç çağrı sayısı, iç sınırdan geçen bayt ve çağıranın bilmek zorunda olduğu ad sayısı.
İlerlemeni kaydetmek ve not almak için Giriş yap
Notlarım
Not almak için giriş yapmalısın.