Divný článek.
Autor třeba poněkud mate čtenáře ohledně DNS load ballanceru. Je trochu divné se tvářit, že je to věc aplikací. Aplikace přece využívají resolver a je to tedy na něm - použije zpravidla první vrácenou položku. Vlastní střídání/prohazování vracených položek provádí DNS server(viz. rrset-order v konfiguraci bindu). V případě MX záznamů je to, pravda, trochu složitější.
Očekával jsem odborný seriál, je to ale jen zmatená školní práce člověka, který ty věci teprve objevuje. Redakce by k tomu měla vždy přidat vysvětlující komentáře :-)
Je to i věc aplikací. Aplikace může použít první vrácenou adresu (a pak to skutečně závisí na serveru, aby adresy prohazoval), a nebo může získat seznam všech adres (respektive nějaké omezené množství, které jí poskytne resolver), a pak je na aplikaci, co s tím seznamem bude dělat. Aplikace si teoreticky může pamatovat/zjišťovat, která IP adresa odpovídá nejrychleji; pokud je nějaká IP adresa nedostupná, může použít další; nebo může poslat každý požadavek na jinou IP adresu, pokud potřebuje poslat víc požadavků (nic z toho bohužel prohlížeče nedělají).
MX je speciální případ, protože tam se i v DNS uvádí priorita záznamů.
No, teď v manu vidím, že gethostbyname() skutečně může vrátit přes **h_addr_list více adres a to, co mám léta zažité je tam jen jako macro pro zpětnou kompatibilitu(první prvek pole). Upřímně, vůbec nevím, kdy k tomu rozšíření došlo :-) Možná už dávno.
Ale skutečně to tak dnes aplikace používají? Třeba, dejme tomu, Firefox? Nevím, do kódu jsem se nedíval....
Jak jsem psal, běžné prohlížeče to bohužel nepoužívají. Některé jiné aplikace to používají – v článku je uvedeno OpenLDAP a obecně se to používá tam, kde se už při návrhu počítalo s tím, že může být jeden server nedostupný. V případě HTTP se spíš dodatečně zjistilo, že přesměrování na jiný server nic nebrání – a moc nechápu, proč se prohlížeče drží tradice a další adresy nezkoušejí. Byl by to ten nejlevnější způsob, jak zajistit jistou odolnost proti výpadkům, a podle mne to nemůže nic rozbít – pokud se prohlížeč nedokáže na první IP adresu připojit, není na tom už co zkazit a případné úspěšné navázání spojení s druhou nebo další IP adresou může být jedině plus. Snad jedině že by krátký výpadek spojení mohl uživateli zrušit session, ale to se dá na straně prohlížeče ošetřit.
Prohlizece to ve skutecnosti pouzivaj ... uplne vsechny. Jen imbecilni vyvojari si toho jeste nestacili vsimnout. Nemaj totiz chudaci cas, musej menit UI.
Protoze copak asi tak dela browser, kdyz se nejdriv de pripojit na ipv6 ... a kdyz to nejde, tak jde na ipv4 ... (pripadne dokonce v rozporu s rfc rovnou posila na oboji a co odpovi driv to pouzije).
Pouziva to napr. Oracle RAC cluster. scan addresa listeneru se resolvuje na 3 IPcka, ktera by mela byt vracena v nahodnem poradi. Uplne 100% to ale neni, napr pokud je mezi DNS a vami BigIP(3DNS). Navic s tim musely byt i nejake jine problemy, protoze od posledni verze OCI ovladace uz obsahuji vlastni resolver a na gethostbyname kaslou. (To mimochodem dela cim dal vice aplikaci).
Ono to ma ale vic aspektu ...
1) dns ti vrati 2-N zaznamu
2) ty zaznamy sou pokazdy v jinym poradi
3) tzn lze to pouzit k rozlozeni zatizeni
4) protoze aplikace (kazda normalni) zkusi nejdriv prvni IP ... a kdyz nevyjde tak druhy, treti ... atd
5) coz zaroven poresi vypadek nejaky IP
Samo to neresi zatizeni toho konkretniho stroje, ale to te v mnoha ohledech naprosto nezajima, jednoduse pokud ti jeden stroj udrzi par tisic klientu, tak to samo o sobe znamena, ze jeden klient generuje naprosto nepatrnou zatez, takze to rozlozeni bude defakto zcela dostatecny.
Jenze ... pokud si klient vybere prvni IP a zrovna tenhle stroj padne nahubu ... tak samozrejme pokud takova situace neni osetrena, tak proste padne nahubu i klient. Coz se ale stane i v pripade, ze to IPcko nekde cestou forwardnes na bezici stroj - protoze se ti stejne rozpadne session.
Takze takovy "uzasny a jednoduchy reseni" ve skutecnosti neresi lautr nic.
Ve finale mas jen jedinou moznost - musi to umet klient. Ty bys sice moh resit predani session na strane serveru, ale to muzes resit leda v pripade, ze ten server nejak korektne vypnes. Pokud padne, tak se nic nikam nepreda. Takze je to na klientovi. Ten musi poznat, ze server nekomunikuje a musi umet komunikaci obnovit s jinym serverem. Coz znamena minimalne resit neco na tema transakce = nepotvrzena transakce neprobehla = poslu ji znova/vynadam uzivateli/.....
Coz je prozmenu neco, o cem autor nema nejspis ani paru - on proste zajistuje provoz neceho, co z principu stejne nemuze fungovat tak jak si mysli.
Jako „session“ se ve světě webových aplikací označuje situace, kdy server pošle klientovi nějaký jednoduchý identifikátor, který klient přibaluje ke každému požadavku (třeba ve formě cookie), a server si k tomuto identifikátoru pamatuje nějaká další data. Takže předání session musí řešit server, protože ten jediný má ta data spojená se session – klient má jenom identifikátor té session, ale ne data. Kvůli tomu, aby ta data měl server a ne klient, se celá ta šaráda se session dělá. Takže klient to opravdu nijak nevyřeší.
Řeší se to tak, že data session si nedrží přímo server, ale existuje nějaké sdílené úložiště, do kterého si pro data session může sáhnout kterýkoli server. Výpadek serveru pak nevadí, když se klient připojí k jinému serveru, ten si vytáhne data ze společného úložiště a jede se dál. Samozřejmě to znamená, že se to kritické místo „akorát“ přesunulo z webového serveru na to úložiště dat pro session.
Jasne, takze reknemez se servery sdilej RAM ... mno a reknemez se klient odesle texbox a jeden ze serveru padne nahubu. Mno a jelikoz druhej server najednou dostane req na zobrazeni odpovedi na neco o cem nic nevi, tak se podiva co ze to ten klient delal naposled, a zjisti, ze naposled se mu zobrazil textbox ... co bude delat dal? Sem vazne zvedav na reseni ala Jirsak ...
Protoze ve skutecnosti si stav session drzi jak server tak predevsim klient, ten jedinej totiz vi, co delal nez server prestal odpovidat. A ten jedinej na to muze korektne reagovat.
Pricemz v pripade browseru zcela obecne plati, ze si kazdej poradi (vice ci mene) dobre s tim, ze server neodpovi (minimalne vrati nejakou pomerne rozumnou chybu a treba umozni akci opakovat), kdezto rozhodne si neporadi s tim, ze server vrati neco zcela neocekavatelnyho (respektive presne to uzivateli zobrazi, coz v tomhle pripade bude treba prave prazdny textbox).
Nacez bude nasledovat fyzicka likvidace obou serveru velkou palici.
Jasne, takze reknemez se servery sdilej RAM
Ne, servery nesdílí RAM. Servery sdílí úložiště session informací. Může to být třeba relační databáze, kterou obvykle servery sdílí i kvůli ukládání dat, ale to moc dobře neškáluje. Častěji se používají různé NoSQL databáze, třeba ty používající protokol memcached apod.
mno a reknemez se klient odesle texbox
Webové prohlížeče neodesílají texboxy, ať už je to cokoli, ale HTTP požadavky. Webové servery na to odpovídají HTTP odpověďmi.
tak se podiva co ze to ten klient delal naposled
Takhle se naštěstí webové aplikace nepíšou – jediný, kdo tenhle princip masově používal, byly staré ASP:NET MVC aplikace. Naštěstí i Microsoft brzy pochopil, že tudy cesta nevede.
zjisti, ze naposled se mu zobrazil textbox ... co bude delat dal?
Nic takového nezjistí. Server z požadavku například zjistí, že uživatel požaduje zobrazení košíku. Jako identifikaci pošle v cookie identifikátor session. Webový server se podívá do sdílené cache, tam zjistí, že tenhle identifikátor session patří uživateli XY – a buď má obsah jeho košíku uložený také v té cache pod tím session ID, tak si ho vytáhne odsud, nebo, pokud je obsah košíku uložený třeba v databázi, načte obsah košíku uživatele XY z databáze.
Protoze ve skutecnosti si stav session drzi jak server tak predevsim klient
Kdyby si stav session držel klient, nemusí si ho držet server. V začátcích webu ale bylo jediné místo, kde si klient mohl držet nějaký stav – cookies. A ty byly omezené velikostí. Proto se do cookies ukládal jen identifikátor a stav si držel server.
klient, ten jedinej totiz vi, co delal nez server prestal odpovidat
Klient nedělal nic. Na klientovi byla zobrazená webová stránka.
(respektive presne to uzivateli zobrazi, coz v tomhle pripade bude treba prave prazdny textbox
Předbíháte dobu, prohlížeče zatím neumí samy od sebe vyměnit část stránky. Prohlížeč pošle požadavek na webovou stránku, server mu vrátí celou webovou stránku a prohlížeč jí celou vykreslí.
JavaScript jsem nezmiňoval schválně. Pak totiž klientem není webový prohlížeč, ale ta javascriptová aplikace – a je čistě na autorech té javascriptové aplikace, jak a jaký stav si bude držet a jak se bude chovat v případě nedostupnosti serveru. Javascriptová aplikace klidně může i obejít to omezení prohlížečů, že resolvují jen jednu IP adresu, a může mít v sobě zadrátováno víc DNS názvů, a zkoušet je, dokud jeden z nich nebude fungovat.
Pokud klient poslal požadavek na server, a server během jeho zpracování havaroval nebo se přerušilo spojení s klientem, klient logicky nedostane od serveru odpověď. Tudíž klient nebude mít žádný důvod domnívat se, že operace skončila úspěšně, právě naopak.
Pokud je klientem přímo webový prohlížeč, zobrazí nějakou chybovou hlášku, třeba že server neočekávaně ukončil spojení. Uživatel může použít tlačítko zpět, čímž se dostane na předchozí stránku s formulářem, kde mu prohlížeč vyplní uživatelem dříve vyplněná data (pokud autor webu prohlížeči v tomto směru nehází klacky pod nohy). Uživatel pak může dát formulář znovu odeslat, a pokud je server mezi tím znovu dostupný (třeba protože loadbalancer vyřadil havarovaný server z clusteru a přesměrovává na zbývající živé servery), formulář se znovu odešle.
Pokud je klientem javascriptová aplikace v prohlížeči, musí návratovou chybu ošetřit její autor, ale zase je jednoduché zobrazit uživateli hlášku „odeslání se nezdařilo, přejete si pokus zopakovat?“ A opět, pokud se mezi tím podaří komunikaci přesměrovat na jiný server, opakovaný pokus se podaří.
Samozřejmě to komplikuje session, která třeba drží údaje o přihlášeném uživateli. Pokud servery používají sdílené úložiště session, není to problém, nový server si prostě data session vytáhne odsud. Pokud se o data session přišlo při pádu serveru, je potřeba data session nějak obnovit, pokud to je možné – např. že se uživatel znovu přihlásí. V případě javascriptové aplikace je to poměrně jednoduché – když se pokusí znovu odeslat data, vrátí se chyba autorizace, aplikace se znovu zeptá uživatele na přihlašovací údaje, přihlásí ho a příslušná data odešle potřetí. Pokud je to klasická formulářová aplikace, je to komplikovanější – je potřeba někam uschovat data, která klient poslal, přesměrovat ho na přihlašovací stránku a po přihlášení ho přesměrovat zpět na stránku, kde byl předtím, a znovu mu vyplnit data, která předtím poslal. Na druhou stranu to je úplně stejné řešení, jakým se řeší vypršení platnosti session, takže uživatelsky přívětivá aplikace to řeší stejně.
Jinak samozřejmě je z tohohle pohledu nejlepší bezestavová aplikace, kdy je klient autentizován při každém požadavku (např. HTTP autentizace). Pak není potřeba na straně serverů řešit nějaké uchování session a perzistenci spojení, prostě může každý požadavek zpracovat jiný server.
Takze co jirsak, dalsi kolecko? Prave si potvrdil to, proti cemu si pred par postama protestoval.
"Jenze ... pokud si klient vybere prvni IP a zrovna tenhle stroj padne nahubu ... tak samozrejme pokud takova situace neni osetrena, tak proste padne nahubu i klient. Coz se ale stane i v pripade, ze to IPcko nekde cestou forwardnes na bezici stroj - protoze se ti stejne rozpadne session."
Ja velmi dobre vim jak se ukladaji sesions ... narozdil od tebe taky vim, to co jirsaka jeste ani nenapadlo, a to ze se mu slozi tcp konexe (protoze dneska bezne browser udrzuje spojeni otevreny), ale jo, treba si do ty svy databaze uklada pekne poradovy cislo kazdyho paketu ... a kdyz mu cestou nejakej vypadne, tak je vprdeli taky.
Jesli sis totiz nevsimla, tak se tu resi situace, ze jeden ze dvou serveru padne nahubu a co se bude dit potom. ukaz mi server, kterej kdyz padne nahubu, tak se jeste pekne slusne rozlouci, posle vsem klientum pozdrav, a pekne vsechno ulozi.
Ukaz mi jediny reseni webu, ktery prezije presmerovani na jinej server. Sem vazne zvedav. Protoze bez spoluprace s klientem to realizovat sice za jistych okolnosti lze, ale to rozhodne nebude "velky" reseni za 20k. Pricezm prave replikace RAM je toho podminkou. Coz mimo jiny zase znamena, ze samozrejme nejde druhej stroj pouzit pro rozkladani zateze. Obecne se totiz da rict, ze se tyhle dva pozadavky navzajem pomerne slusne vylucujou.
ukaz mi server, kterej kdyz padne nahubu, tak se jeste pekne slusne rozlouci, posle vsem klientum pozdrav, a pekne vsechno ulozi.
Vtip je v tom, že jste stále nepochopil, že když server neočekávaně odpadne, klient nedostane požadovanou odpověď a bude ve stavu, jako kdyby nic neodeslal. Váš předpoklad, že server nejprve stihne odeslat klientovi kompletní odpověď, a teprve pak se poroučí do věčných lovišť, je chybný. A když to tak náhodou je, je kolečko požadavek–odpověď dokončené, takže pád serveru ničemu nevadí – příští požadavek prostě půjde na jiný server.
Ukaz mi jediny reseni webu, ktery prezije presmerovani na jinej server.
Všechna cloudová řešení – cloud je na tomhle principu postaven. Takže třeba Google, GMail, Seznam, Dropbox, YouTube, Mapy.cz a tisíce dalších.
Pricezm prave replikace RAM je toho podminkou.
Replikace RAM je nebetyčná hloupost hodná vašeho jména. Už jsem vám vysvětloval, že pokud je potřeba držet stav na serveru, řeší se to sdíleným úložištěm session nejčastěji v nějaké NoSQL databázi. A ještě lepší je nedržet stav vůbec.
Na co pozdrav na rozloučenou? Ty když přijdeš do místnosti, kde je zhasnuto a zeptáš se, jestli tam někdo je, dostaneš odpověď "není", když je prázdná?
Logicky, na straně serveru
1. Dostanu požadavek
2. Zpracuju požadavek
3. Pošlu výsledek
Když selže 1, nedostanu odpověď. Server neví, že po něm někdo něco chce.
Když selže 2, nedostane odpověď, nebo je odeslána chyba.
Když selže 3, neodejde kompletní odpověď.
Takže pokud není odpověď, ber to jako rozloučení v kterékoliv fázi...
Web v browseru a na serveru běží na aplikační vrstvě TCP/IP. Fragmentace, MTU, IPSEC a podobně ho nezajímá. Došlo všechno, nebo nic.
Zapomeň na replikaci RAM, dej si tam obecný uložiště. Sdílený mezi web servery (řešíme front end web server).
1. Přijde login request, podívá se do DB klientů (ta musí být sdílená), vytvoří session, vrátí token. Klientovi nepřišel token - login fail, může zkusit jiný server. Ten buďto najde platnou session pro klienta (nepovedlo se potvrzení), nebo vyrtvoří novou.
2. Uživatel něco odešle. Nedostane ACK, zkusí to znovu na jiný server, ten buďto zná detaily a pošle předchozí výsledek, nebo ne a operace proběhne znovu,...
3. ...
Data a tokeny jsou uloženy v nějaké cache, klidně jako JSON na ramdrive, v DB, jakkoliv. Ale to není starost front endu, ten se jenom uložiště ptá na session a existenci/výsledek operace.
Petr M: Jenom doplním, že pokud se session používá jenom pro identifikaci uživatele, lze se snadno obejít i bez toho sdíleného úložiště. Stačí identifikaci uživatele uložit do tokenu (spolu s datem expirace) a digitálně ho podepsat. Token pak dokáže ověřit kterýkoli server bez nutnosti mít nějaké sdílené úložiště session. Nevýhodou takového řešení je, že není možné vynutit odhlášení uživatele před expirací tokenu.
2Petr M: Co to zase proboha zvanis ... zadny SDILENY uloziste NEMAS, mas DVA servery, mezi nima mas nejspis soho switch za 3 kila, mozna v kombinaci s routerem za petikilo.
A resis, jak vyresit, ze provoz je ... BEZ VYPADKU. A ZAROVEN, jak rozlozis na ty dva servery ZATIZENI.
Pricemz JA tvrdim, ze pokouset se preforwardovat IPcko z jednoho na druhe je uplne khovnu, protoze to neresi vubec NIC, to je to jediny, o cem je tu celou dobu rec.
Nemluve o tom, ze 90% webu (vcetne roota, lupy a dalsich) ti pri opakovanym odeslani vytvori novej zaznam.
zadny SDILENY uloziste NEMAS
Mohl byste nám popsat, co zhruba tak ty vaše dva servery dělají, a co je uložené v té session? Webové servery totiž často čtou data ze sdíleného úložiště (zobrazení článků, zobrazení e-mailů, zobrazení zboží), zapisují do sdíleného úložiště (komentáře k článku, e-mail k odeslání, objednávku zboží). V session obvykle bývá identifikace přihlášeného uživatele, přičemž pro přihlášení uživatele obvykle potřebujete ověřit přihlašovací jméno a heslo ve sdíleném úložišti.
Jistě, existují weby, které nepotřebují sdílené úložiště – třeba poskytují jenom statické stránky. Jenže takové weby zase nemají nic uloženého v session a každý požadavek může přijít na jiný webový server.
Pricemz JA tvrdim, ze pokouset se preforwardovat IPcko z jednoho na druhe je uplne khovnu, protoze to neresi vubec NIC, to je to jediny, o cem je tu celou dobu rec.
To je zvláštní, že to všem provozovatelům cloudu funguje. Vy třeba když vyhledáváte na Google, tak nějak zaznamenáte, že váš druhý dotaz šel na jiný server, než první dotaz? Poznáte na YouTube, že vás začal odbavovat jiný server?
Nemluve o tom, ze 90% webu (vcetne roota, lupy a dalsich) ti pri opakovanym odeslani vytvori novej zaznam.
Opakovaném odeslání čeho? Nový záznam v čem?
ale jo, treba si do ty svy databaze uklada pekne poradovy cislo kazdyho paketu ... a kdyz mu cestou nejakej vypadne, tak je vprdeli taky.
Ty jsi dobry expert, cislo paketu te zajima na transportni vrstve a na vyssi urovni, nedejboze na urovni protokolu http, k tomu pristup vubec nemas.
Jesli sis totiz nevsimla, tak se tu resi situace, ze jeden ze dvou serveru padne nahubu a co se bude dit potom.
Na urovni protokolu HTTP se prijme bud cely request nebo odesla cela response. Proste se ten pozadavek nezpracuje a klient muze ohlasit, ze nedostal odpovidajici response od serveru. Opacne, server pozadavek zpracuje, ale klient si nevyzvednet response. Muze dat refresh a data se nactou podle aktualniho stavu.
Ukaz mi jediny reseni webu, ktery prezije presmerovani na jinej server. Sem vazne zvedav. Protoze bez spoluprace s klientem to realizovat sice za jistych okolnosti lze, ale to rozhodne nebude "velky" reseni za 20k. Pricezm prave replikace RAM je toho podminkou
Naprosto jednoduse. Nastavis si pro example.com dve IP/CNAME (srv1.example.com, srv2.example.com), predpokladejme, ze loadbalancing bude nejak zarizeny. Jednotlive hodnoty session si budes ukladat v nejake databazi (postgres, mysql, bdb, nejake nosql), prijde pozadavek, prislusny server srv1/srv2 si data vytahne z databaze, provede odpoved klientovi a zmenene hodnoty session ulozi opet do databaze.
Opravdu me prekvapuje, ze odbornik jako ty, takovou zakladni konfiguraci nezna.
nedokazes si ani precist zadani.
Pozadavek zni, ze provoz bude bez vypadku komunikace (o webu nebyla vubec rec).
Myslis? Nevim kdo se tu ptal:
Ukaz mi jediny reseni webu, ktery prezije presmerovani na jinej server.
Mas dva stroje a mezi nima blbej switch, nic jinyho nemas.
Bolelo by to moc, kdybys jednou priznal, ze necemu nerozumis. Nejdriv pozadujes sdilenou RAM, ted, ze mezi pocitaci je jen blby switch, pricemz pro realne nasazeni jsou tyhle pozadavky absurdni a zbytecne. Sdilene uloziste pro sessions je naprosto bezna a standardni zalezitost, stejne jako dedikovany server pro databazi.
No ale to se od webu dostaneme k DB, od front endu k back endu.
Fakt je problém na fyzickým serveru mít dva virtuály, v jednom front end a ve druhým back end, který skladuje ty sessions? A je problém zrcadlit stajnou databázi na obou strojích s tím, že front end primárně sahá na data na stejné fyzické mašině a když se k nim nedostane, tak sáhne na vedlejší stroj?