Ders 09 / 11
Uzak Sunucuya Bağlanma
Sunucu ağın ötesine geçtiğinde bağlantının eklediği adımın sayılması: aynı üç araçlık zincir, üç sunucunun tamamı aynı makinedeyken 6 istek, 6 yanıt, 179 zarf belirteci ve 6 gidiş-dönüş ödüyor; iki sunucu uzak aktarıma taşındığında mesaj sayısı değişmeden gidiş-dönüş 9'a çıkıyor, uzak sunucu başına birer kimlik ve yetki adımı eklendiğinde sayım 10 istek, 10 yanıt, 289 belirteç ve 17 gidiş-dönüşe yükseliyor. Anlaşılan araç kümesi üç kurulumda da üç araç, sonuç üçünde de aynı; eklenen 110 belirtecin 64'ü yalnız zarf sabitidir. Ölçü koşumdan bağımsızdır: üç ayrı abonede sayım birebir aynı çıkıyor.
İçindekiler
Bir önceki derste sunucu istemciyle aynı makinede duruyordu ve bağlantı bir süreç sınırından ibaretti. O sınır iki işi birden görüyordu: zarfı taşıyordu ve karşı tarafın kim olduğu sorusunu ortadan kaldırıyordu, çünkü süreci başlatan istemcinin kendisiydi. Sunucu ağın ötesine geçtiğinde bu birliktelik bozulur. Aktarım aynı zarfı taşımayı sürdürür, ama karşı tarafın kim olduğu ve neye yetkili olduğu artık ayrı ayrı sorulması gereken iki sorudur. Kimlik doğrulama ve yetkilendirme yordamı Kimlik Doğrulama ve Yetkilendirme kursunda ölçüldü ve burada tekrarlanmaz. Ölçülen tek şey uzak bağlantının eklediği adımdır.
- GE41. Ortam, üç sunucu, zarf sayımı ve yetenek uzlaşması kurgudur; gerçek bir sunucu, istemci kitaplığı ya da çalışma zamanı çağrılmaz. Tohum 20260218.
- GE42. Kimlik adımı ve yetki adımı, uzak aktarımdaki her sunucu için birer istek ve yanıt çiftidir. Hiçbir belirteç biçimi, akış ya da standart kurulmaz; sayılan şey mesajdır.
- GE43. Yetki adımı sonucu değiştirmez: verilen yetki, istemcinin zaten uyguladığı izin listesidir. Ölçü böyle yalıtılır — üç kurulumda değişen tek şey bedeldir.
- GE44. “Hepsi yerel” kurulumu karşılaştırma tabanıdır: aynı üç sunucu, aynı sürümler, tek farkla aktarım alanı.
- GE45. Protokolsüz taban zarf saymaz: araç ders içinde tanımlıdır, el sıkışması yoktur, üç işlev doğrudan çağrılır. Bu dersin bütün sayı sütunlarında sıfırdır.
Aynı İş, İki Kurulum
Blok ortak tanımı kurar: kurgu ölçüm ağı, üç kurgu sunucu, zarf sayacı, yetenek uzlaşması ve araç
çağrısı. olcum yerel, tarife ve kayit uzak aktarımdadır.
# KURGUDUR. Olcum aginin abone kayitlari, uc sunucu, zarf sayaci ve yetenek # uzlasmasi ders icinde tanimlanir; gercek bir sunucu ya da istemci cagrilmaz. TOHUM, M32 = 20260218, 0xFFFFFFFF def uretec(t): x = ((t ^ (t >> 16)) * 2246822507) & M32 x = ((x ^ (x >> 13)) * 3266489909) & M32 s = [(x ^ (x >> 16)) & M32] def sonraki(): s[0] = (s[0] * 1664525 + 1013904223) & M32 return s[0] / 4294967296 return sonraki def belirtecle(m): b = [] for s in str(m).lower().replace(",", " , ").split(): while len(s) > 5: b.append(s[:5]) s = s[5:] b.append(s) return b BOLGE = ["dogu", "bati", "kuzey", "guney", "merkez"] TIP = ["mesken", "isyeri"] ABONE = {} for i in range(60): r = uretec(TOHUM + 31 * i) onceki = 10000 + int(r() * 80000) ABONE[f"A{i + 1:03d}"] = {"bolge": BOLGE[int(r() * 5)], "tip": TIP[int(r() * 2)], "onceki": onceki, "simdiki": onceki + int(r() * 70)} BASAMAK, USTU, ISYERI_KAT = ((10, 4), (25, 7), (40, 11)), 16, 2 def _bedel(m3, tip): kalan, alt, top = m3, 0, 0 for ust, birim in BASAMAK: dilim = min(kalan, ust - alt) if dilim <= 0: break top += dilim * birim kalan -= dilim alt = ust return (top + kalan * USTU) * (ISYERI_KAT if tip == "isyeri" else 1) def t_sayac(abone=None, **_): a = ABONE.get(abone) return {"hata": "abone yok"} if a is None else { "onceki": a["onceki"], "simdiki": a["simdiki"], "tip": a["tip"]} def t_tuketim(onceki=None, simdiki=None, **_): if onceki is None or simdiki is None: return {"hata": "eksik alan"} f = simdiki - onceki return {"m3": f + 100000 if f < 0 else f} def t_tarife(m3=None, tip="mesken", **_): return {"hata": "eksik alan"} if m3 is None else {"tutar": _bedel(m3, tip)} def t_bolge(bolge=None, **_): if bolge not in BOLGE: return {"hata": "bolge yok"} n = sum(1 for a in ABONE.values() if a["bolge"] == bolge) return {"bolge": bolge, "abone": n} def t_kayit(abone=None, sutun=None, deger=None, **_): if not (abone and sutun and deger is not None): return {"hata": "eksik alan"} return {"yazildi": True} SUNUCU = { "olcum": {"surum": 2, "aktarim": "yerel", "arac": {"sayac_oku": {"islev": t_sayac, "alan": ("abone",), "yan_etki": False}, "tuketim": {"islev": t_tuketim, "alan": ("onceki", "simdiki"), "yan_etki": False}}, "kaynak": ("abone_listesi",), "istem": ()}, "tarife": {"surum": 1, "aktarim": "uzak", "arac": {"tarife": {"islev": t_tarife, "alan": ("m3", "tip"), "yan_etki": False}}, "kaynak": ("basamak_tablosu",), "istem": ("bedel_aciklamasi",)}, "kayit": {"surum": 3, "aktarim": "uzak", "arac": {"bolge_ozet": {"islev": t_bolge, "alan": ("bolge",), "yan_etki": False}, "kayit_yaz": {"islev": t_kayit, "alan": ("abone", "sutun", "deger"), "yan_etki": True}}, "kaynak": (), "istem": ()}, } ISTEMCI_SURUM = {"olcum": 2, "tarife": 1, "kayit": 2} # kayit sunucusu ileride IZIN = ("sayac_oku", "tuketim", "tarife", "bolge_ozet") # kayit_yaz izin listesinde yok SAYIM = {"istek": 0, "yanit": 0, "bildirim": 0, "belirtec": 0, "gidis_donus": 0} def mesaj(tur, govde, aktarim="yerel"): """KURGU zarf. Gercek bir protokol uygulanmaz; sayilan sey zarfin bedelidir.""" SAYIM[tur] += 1 b = len(belirtecle(govde)) + 8 # zarf sabiti SAYIM["belirtec"] += b if tur == "istek": SAYIM["gidis_donus"] += 2 if aktarim == "uzak" else 1 return b def elsikismasi(istemci_surum=None, izin=None): """Yetenek uzlasmasi: surum uyusmazligi ve izin listesi arac kumesini daraltir.""" istemci_surum = ISTEMCI_SURUM if istemci_surum is None else istemci_surum izin = IZIN if izin is None else izin anlasilan, dusen = {}, [] for ad, s in SUNUCU.items(): mesaj("istek", f"yetenek sor {ad}", s["aktarim"]) mesaj("yanit", f"yetenek bildir {ad} surum {s['surum']} " + " ".join(s["arac"]) + " " + " ".join(s["kaynak"])) if istemci_surum.get(ad, 0) < s["surum"]: dusen.append((ad, "surum", s["surum"], istemci_surum.get(ad, 0))) continue for t, tan in s["arac"].items(): if t not in izin: dusen.append((ad, "izin", t, None)) continue anlasilan[t] = dict(tan, sunucu=ad, aktarim=s["aktarim"]) return anlasilan, dusen def cagir(anlasilan, ad, durum): if ad not in anlasilan: return {"hata": "arac bildirilmedi"} t = anlasilan[ad] kw = {a: durum[a] for a in t["alan"] if a in durum} mesaj("istek", f"{ad} " + " ".join(f"{k} {v}" for k, v in kw.items()), t["aktarim"]) s = t["islev"](**kw) mesaj("yanit", " ".join(f"{k} {v}" for k, v in s.items())) return s
Kimlik Adımı, Yetki Adımı, Gidiş-Dönüş
İkinci blok aynı zincirin bedelini üç kurulumda sayar. Ortadaki kurulum ayırıcıdır: sunucular uzak aktarımdadır ama kimlik ve yetki adımı henüz eklenmemiştir, yani yalnız aktarımın kendi farkı görünür.
UZAK = {ad: dict(s) for ad, s in SUNUCU.items()} YEREL = {ad: dict(s, aktarim="yerel") for ad, s in SUNUCU.items()} ZINCIR = ("sayac_oku", "tuketim", "tarife") def on_adim(sunucular): """Uzak aktarimdaki her sunucu icin bir kimlik ve bir yetki adimi.""" kimlik = yetki = 0 for ad, s in sunucular.items(): if s["aktarim"] != "uzak": continue mesaj("istek", f"kimlik sun {ad}", "uzak") mesaj("yanit", f"kimlik kabul {ad}") kimlik += 1 mesaj("istek", f"yetki iste {ad} arac kumesi", "uzak") mesaj("yanit", f"yetki verildi {ad} izin listesi") yetki += 1 return kimlik, yetki def kurulum(sunucular, on_adimli, abone="A017"): """Sunucu tablosunu gecici olarak kurulumunkiyle degistirir, sayaclari sifirlar.""" tablo = {ad: dict(s) for ad, s in sunucular.items()} onceki = {ad: dict(s) for ad, s in SUNUCU.items()} for k in SAYIM: SAYIM[k] = 0 SUNUCU.clear() SUNUCU.update(tablo) try: kimlik, yetki = on_adim(SUNUCU) if on_adimli else (0, 0) anlasilan, _ = elsikismasi() durum = {"abone": abone} for ad in ZINCIR: durum.update(cagir(anlasilan, ad, durum)) finally: SUNUCU.clear() SUNUCU.update(onceki) return dict(SAYIM, kimlik=kimlik, yetki=yetki, arac=len(anlasilan), sonuc=durum.get("tutar")) print("kurulum kimlik yetki istek yanit belirtec gidis-donus anlasilan sonuc") for etiket, tablo, on in (("hepsi yerel", YEREL, False), ("uzak, on adimsiz", UZAK, False), ("uzak, on adimli", UZAK, True)): s = kurulum(tablo, on) print(f"{etiket:<18} {s['kimlik']:>6} {s['yetki']:>5} {s['istek']:>5} {s['yanit']:>5}" f" {s['belirtec']:>8} {s['gidis_donus']:>11} {s['arac']:>9} {s['sonuc']:>5}") alan = ("istek", "yanit", "belirtec", "gidis_donus", "arac") uc = [kurulum(UZAK, True, a) for a in ("A017", "A042", "A003")] print("\nuc ayri abone, ayni kurulum. sayim ayni mi:", len({tuple(s[a] for a in alan) for s in uc}) == 1, " sonuclar:", [s["sonuc"] for s in uc])
kurulum kimlik yetki istek yanit belirtec gidis-donus anlasilan sonuc hepsi yerel 0 0 6 6 179 6 3 844 uzak, on adimsiz 0 0 6 6 179 9 3 844 uzak, on adimli 2 2 10 10 289 17 3 844 uc ayri abone, ayni kurulum. sayim ayni mi: True sonuclar: [844, 68, 211]
Sayının Okunması
Üç satırın son iki sütunu aynıdır: anlaşılan araç kümesi üç araç, hesabın sonucu 844. Uzağa taşınmak istemcinin eline yeni bir yetenek vermedi, elindekini de almadı. Değişen yalnız bedeldir ve bedel iki ayrı yerden gelir.
Birincisi aktarımın kendisidir. Ortadaki satırda istek 6, yanıt 6 ve belirteç 179 olarak
birinci satırla birebir aynı kalıyor; yalnız gidiş-dönüş 6’dan 9’a çıkıyor. Altı isteğin üçü
uzak sunuculara gidiyor (tarife ve kayit sunucularına yetenek sorusu, tarife aracına çağrı)
ve uzak bir istek bir yerine iki gidiş-dönüş sayılıyor. Fark +3’tür ve tek bir mesaj bile
eklenmeden ortaya çıkar. Bu, kursun ikinci iddiasının bu derse düşen örneğidir: aynı sözleşme, aynı
mesaj sayısı, daha pahalı bağlantı.
İkincisi kimlik ve yetki adımıdır. Üçüncü satırda iki uzak sunucunun her biri için bir kimlik ve bir yetki adımı yürüyor: 2 kimlik, 2 yetki, yani 4 istek ve 4 yanıt. Mesaj sayısı 6’dan 10’a, belirteç 179’dan 289’a, gidiş-dönüş 9’dan 17’ye çıkıyor. Eklenen 8 mesajın hepsi uzak olduğu için gidiş-dönüş katkısı 8’dir. Eklenen 110 belirtecin 64’ü yalnız zarf sabitidir (8 mesaj, mesaj başına 8 belirteç); geri kalan 46 belirteç adımların kendi gövdesidir. Bağlantıyı güvenli saymanın bedeli, taşınan bilgiden çok zarfın kendisidir.
Yerel tabana göre toplam fark şudur: +4 istek, +4 yanıt, +110 belirteç, +11 gidiş-dönüş, ve kazanılan sıfır araç. Protokolsüz taban bu tablonun daha da altındadır: araç ders içinde tanımlı olduğunda zincir 0 istek, 0 yanıt, 0 belirteç ve 0 gidiş-dönüşle aynı 844’ü üretir. Uzak bağlantının kazandırdığı şey bu derste görünmez, çünkü ortada tek bir istemci vardır.
Yetki adımının sonucu bu kurulumda izin listesiyle aynıdır ve bu bir tesadüf değil, ölçüyü yalıtmak için verilmiş bir karardır. Uzak tarafın istemciye kendi izin listesinden dar bir küme vermesi mümkündür; öyle olsaydı fark anlaşılan araç sütununda görünürdü, bedel sütunlarında değil. Sütunun üç satırda da 3 kalması, bu dersin ölçtüğü şeyin yetkinin içeriği değil adımın kendisi olduğunu söyler. Yetkinin daraltıcı olduğu hâl kursun son dersine bırakılır ve orada bir sayım olarak açılır.
Son satır ölçünün koşumdan bağımsız olduğunu gösterir. Aynı kurulum üç ayrı abone için koşturuluyor: sayım dört sütunun hepsinde birebir aynı, sonuçlar 844, 68 ve 211. Sayılan şey sözleşmenin biçimidir, taşınan verinin büyüklüğü değil; bu yüzden tabloda tohuma bağlı bir band yoktur.
Adımın Oturuma Bağlanması
Yukarıdaki tablo tek bir zincir içindir. Kimlik ve yetki adımının kaç kez ödendiği ise ayrı bir karardır: adım oturuma bağlanabilir ve bağlantı boyunca bir kez yürür, ya da her iş parçasında yeniden yürür. İki seçenek aynı işi yapar; ayrıldıkları yer sayımdır.
ABONELER = ("A017", "A042", "A003", "A055") def oturumda(kez, her_zincirde): """Bir oturumda kez adet zincir kosar. her_zincirde True ise kimlik ve yetki adimi her zincir icin yeniden odenir, degilse oturum basina bir kez.""" for k in SAYIM: SAYIM[k] = 0 adim = 0 if not her_zincirde: kimlik, yetki = on_adim(SUNUCU) adim += kimlik + yetki anlasilan, _ = elsikismasi() for abone in ABONELER[:kez]: if her_zincirde: kimlik, yetki = on_adim(SUNUCU) adim += kimlik + yetki durum = {"abone": abone} for ad in ZINCIR: durum.update(cagir(anlasilan, ad, durum)) return dict(SAYIM, adim=adim) print("zincir adim yenileme adim istek yanit belirtec gidis-donus") for kez in (1, 2, 4): for her in (False, True): s = oturumda(kez, her) print(f"{kez:>6} {'her zincirde' if her else 'oturum basina':<14}" f" {s['adim']:>5} {s['istek']:>5} {s['yanit']:>5} {s['belirtec']:>8}" f" {s['gidis_donus']:>11}")
zincir adim yenileme adim istek yanit belirtec gidis-donus
1 oturum basina 4 10 10 289 17
1 her zincirde 4 10 10 289 17
2 oturum basina 4 13 13 369 21
2 her zincirde 8 17 17 479 29
4 oturum basina 4 19 19 529 29
4 her zincirde 16 31 31 859 53
Tek zincirde iki satır birebir aynıdır; ayrım orada ölçülemez. Zincir sayısı arttıkça iki sütun ayrışır: dört zincirde adım 4’e karşı 16, istek 19’a karşı 31, belirteç 529’a karşı 859 ve gidiş-dönüş 29’a karşı 53 olur. Fark +12 istek, +12 yanıt, +330 belirteç ve +24 gidiş-dönüştür; iş aynıdır, sonuçlar aynıdır. Oturum başına bağlanan adımda sabit bedel dört mesajda kalır ve zincir başına düşen pay küçülür; her zincirde yenilenen adımda sabit bedel diye bir şey yoktur, çünkü sabit olan kalem her seferinde yeniden ödenir.
Ayrımın ölçülebilir olması için zincir sayısının birden büyük olması gerekir. Tek zincirlik bir ölçümde iki tasarım arasındaki fark sıfırdır ve bu, sıfır fark demek değildir: küme farkı göstermeye yetmiyordur. Bu kursun boyu üç sunucu ve beş bildirilen araçla sınırlıdır; ölçülen her farkın hangi büyüklükte görünür olduğu tabloda yazılmadıkça sayı eksiktir.
Özet
- Uzak aktarım, mesaj sayısını değiştirmeden gidiş-dönüşü büyütür: aynı 6 istek yerelde 6, uzakta 9 gidiş-dönüş sayar.
- Kimlik ve yetki adımı uzak sunucu başına iki istek ve iki yanıttır; iki sunucuda toplam 8 mesaj, 110 belirteç ve 8 gidiş-dönüş ekler.
- Eklenen 110 belirtecin 64’ü zarf sabitidir; bedelin çoğu taşınan bilgi değil zarftır.
- Üç kurulumda da anlaşılan araç kümesi üç araç ve sonuç 844’tür: bedel arttı, yetenek artmadı.
- Adımı oturuma bağlamak dört zincirde 12 istek, 330 belirteç ve 24 gidiş-dönüş kazandırır; tek zincirde iki tasarım arasındaki fark ölçülemez.
- Sayım üç ayrı abonede birebir aynıdır; ölçü koşumdan bağımsızdır.
Sonraki Adım
Bu dersin tablosu tek bir istemci içindir ve o istemci için protokol saf bedeldir: 10 istek, 10 yanıt, 289 belirteç ve 17 gidiş-dönüş ödeyip ders içinde tanımlı bir aracın verdiği sonucun aynısını alır. Tanımın karşı tarafta durmasının karşılığı ise henüz hiç sayılmadı. Aynı sunucu bir ikinci istemciye takıldığında ne oluyor: bu bedel yeniden mi ödeniyor, yoksa bir kısmı bir kez mi ödendi? Sonraki ders aynı sunucuyu iki ayrı istemci türüne bağlar ve kaç satır tanımın ile kaç mesajın yeniden ödendiğini sayar; taşınabilirliğin ölçüsü budur.
İlerlemeni kaydetmek ve not almak için Giriş yap
Notlarım
Not almak için giriş yapmalısın.