Hezké shrnutí toho jak HTTP/2 vypadá a co umí, nicméně bych měl výhradu proti větě "Kromě toho se předpokládá, že HTTP/2 bude typicky nasazeno v kombinaci s TLS, tudíž stejně nepřipadá v úvahu, že by někdo s Telnetem simuloval WWW klienta a testoval odpovědi serveru." - Takovou věc dělám téměř denně. Samozřejmě ne obyčejným telnetem, ale přes openssl s_client. HTTP/2 mi takovou věc podstatně ztíží, takže si pak budu muset pomoci třeba curlem, který ale na AIXech, se kterými pracuji, často chybí.
Přehledně, srozumitelně a s minimem emocí sepsané, nezbývá než poděkovat.
Celé ty binární hlavičky znamená pouze to, že se pošle typ hlavičky (odkaz na název a hodnotu z tabulky, odkaz na název z tabulky a nová hodnota, nový název i hodnota), a podle typu pak buď index do tabulky hlaviček, nebo délka textového řetězce a za ní samotný textový řetězec. A ty číselné údaje se neposílají jako dekadické číslo zapsané v ASCII (jako to bylo v HTTP/1.1), ale zakódují se binárně. Obecně třeba když víte, že potřebujete poslat jedno číslo v rozsahu 0–3 a druhé číslo v rozsahu 0–63, nadefinuje se v protokolu, že se pošle jeden oktet (bajt, osm bitů), kde první dva bity budou představovat první číslo a zbývajících 6 bitů bude reprezentovat to druhé číslo. V HTTP/2 je to trošku složitější, protože tam není předem omezená velikost čísla, ale i takovýhle způsob kódování se běžně používá – asi nemá smysl tady opisovat specifikaci. Texty v hlavičkách pak ještě mohou být komprimovány Huffmanovo kódováním.
Tady máte příklad ze specifikace. Hlavička :path
s hodnotou /sample/path
040c 2f73 616d 706c 652f 7061 7468Když se na to podíváte jako na ASCII text s výpisem kontrolních znaků pomocí stříšky, bude to: ^D^L/sample/pathTexty jsou tam jednak kvůli hodnotám hlaviček (host name, datum a čas, mime-typy, cookie…), jednak proto, že si každý může vytvořit svůj vlastní název hlavičky (nestandardní hlavičky se uvozují „X-“).
Třeba to, že ty dodatečné parametry posílá i server klientovi, takže nemá žádné URL za GETem, kam by ty parametry přidal.
Mimochodem, jednou z hlaviček, která původně nebyla ve standardu (HTTP/1.0) a nejprve ji svévolně začali používat klienti i servery, a až po té byla doplněna do standardu HTTP/1.1, je hlavička Host
. Protože na začátku nikoho nenapadlo, že se poruší oddělení jednotlivých vrstev síťových protokolů, doménové jméno přestane označovat jen počítač a bud označovat i "website", takže na jedné IP adrese bude hostováno mnoho různých "website" s různými doménovými jmény, a tudíž bude nutné zavléct doménové jméno i do aplikačního protokolu. Myslíte si, že to byla chyba v návrhu protokolu HTTP/1.0?
host name - při šifrované komunikaci stejně bude muset probíhat jakási předkomunikace, během ní by šel pro hostname domluvit číselný identifikátor, takže hostname v textové podobě být nemusí,
datum a čas - jsou čísla, tedy nemusí být přenášeny v textové podobě, v binární podobě se navíc zjednoduší interpretace, neboť nebude nutné převádět čas z textu na číslo,
mime-typy - proč pro ně také neexistuje tabulka, jako pro hlavičky?
cookie - mohou být číselná, nas hodnoty mohou být převáděny pomocí tabulky,
k čemu tedy texty v binárních hlavičkách?
k host name : Tohle tam překvapivě je. Přečti si znova kapitolu "komprese hlaviček" a zjistíš, že je to vlastně to, co navrhuješ. Akorát je to jednodušší a není to omezené na host name.
k datum a čas : Takže místo ISO standardu mají použít nějaký vlastní nový způsob reprezentace data? Fakt?
k mime : Opět. Mime je standard, který se používá všude možně. Vymýšlet nějaký vlastní formát za ušetření pár B v hlavičce fakt nestojí.
hostname: no, akorát se na to nějak nedá moc spoléhat při prvním dotazu na tento server, protože nikdo neví, co v té tabulce je.
datum a čas: z hlediska zpracování by bylo mnohem jednodušší zpracovávat binární vyjádření času, kdybych věděl, třeba že první bajt jsou sekundy, druhý bajt jsou minuty, třetí bajt jsou hodiny, čtvrtý bajt je den, pátý bajt je měsíc a šestý a sedmý bajt je rok a třeba osmý bajt je den v týdnu.
V čem je komplikovanější získávat přímo hodnoty, než přechroustávat nějaký textový řetězec a převádět ho na tyto požadované hodnoty?
mime: Proč vlastní formát? stačila by tabulka a čtyřbajtové vyjádření by postačovalo pro pokrytí všech existujících mime typů. V jedné hlavičce je to sice jenom pár bajtů, ale při tom, kolik hlaviček denně proletí sítí, by to pár Tera uspořených bajtů udělat mohlo.
A navíc, tu tabulku by ani klient ani server nepotřebovali, těm by stačilo jenom to číslo, převod na mime potřebuje akorát tak uživatel. Takže programy by si ušetřili další parsování toho, co že jim to vlastně server posílá.
Na začátku je prázdná. Cílem http/2 není ušetřit pár přenesených bytů, ale pár dotazů a odpovědí. Nezdržuje to přenášení dat, ale latence dotazů a odpovědí.
To už teda raději unix timestamp, nebo ntp datestamp. To co navrhuješ ty má nevýhody z obou stran. Je to zvytečně velké, nedá se to přímo použít a navrch je to ještě nečitelné.
S tím mime je to vtip? Kolik bytů si myslíš, že bys ušetřil? Jen hlavičky TCP/IP mají minimálně 40B. Data, kterých se to mime týká mají obvykle sakra víc. Nesnažíš se šetřit na dost blbém místě?
Jen drobná korekce: Na začátku není prázdná - obsahuje pevně definovanou statickou část, ve které jsou nejběžněji používané hlavičky a jejíž obsah je definován specifikací - viz https://tools.ietf.org/html/draft-ietf-httpbis-header-compression-12#appendix-A
Na ni navazuje dynamická část, která je na začátku prázdná a plní se podle potřeb konkrétního spojení. Nechtěl jsem v textu rozpitvávat úplně všechny detaily, ale asi jsem měl ;-)
Pokud není cílem ušetřit pár bytů, tak binární hlavička nedává smysl. Zvlášť když mají být komprimované. U textu, zvlášť ASCII je komprese obvykle větší, než u binárních dat. Takže po komprimaci bych výsledky čekal více méně stejné.
Záleží, na co to použiješ. UNIX stamp má totiž jednu mouchu - vzhledem k různým počtům dnů v měsíci, přestupným dnům, přestupným sekundám, je získání třeba pořadového čísla dne v měsíci ne úplně triviální záležitostí - resp. je jednodušší ze data, kde jsou jednotlivé jeho části dány svojí hodnotou vypočítat unix stamp než naopak.
Třeba v hlavičce jaký typ souboru klient očekává by se tím takových 20 B a víc klidně ušetřit mohlo. Takhle těch 20 B zní bezzubě, ale když si vezmeš kolik hlaviček sítí projde denně, pár Tera to dá. Proč myslíš, že se u šroubů místo hlav velikosti 16 začali u některých výrobců dělat hlavy velikosti 15? Aby ušetřili materiál. Na jednom šroubu je to sice nic, ale v těch milionových sériích je to znát hodně.
Dává to smysl. Jednotlivé řetězce v HTTP hlavičce jsou jednoznačné ale díky tomu, že je to text, tak se kolem nich vyskytují různé počty mezer, tabulátory a různé druhy konců řádků.
Tenhle binec pochází právě z toho, že je to text a použití binárního protokolu dost efektivně omezuje tuhle kreativitu.
Mime typů je neomezené množství, takže konečná tabulka do standardu by se pro ně dělala těžko. Cookie nemohou být číselná, prohlížeč si do cookie může uložit libovolný text. Třeba si může do cookie uložit jméno, které uvádíte u svých komentářů na Rootu, abyste ho nemusel pokaždé znovu vyplňovat. To byste chtěl, aby jste si musel jméno "Oxymoron" zaregistrovat do HTTP standardu, aby jeho hodnota mohla být součástí cookie?
Další textové hlavičky jsou třeba hlavička Location pro přesměrování. Opět, to se má podle vás do standardu zařadit seznam všech adres, na které je možné přesměrovat, a když budete chtít přesměrovávat na novou adresu, budete si muset podat žádost a za 16 let se to dostane do příští verze standardu?
Přiznám se, že jsem od minulého článku pořád úplně nepochopil ten server push. Ano, je hezké, že klient může serveru říct, které soubory mu nemá posílat, ale přiznám se, že mi pořád není úplně jasná strategie, pořád nějak nedokážu přijít na to, jak může klient už při prvním požadavku na načtení stránky sdělit serveru, které soubory mu nemá posílat.
krok 1) klient požádá o soubor (v tuto chvíli klient neví, které další soubory bude stránka potřebovat),
krok 2) server pošle soubor a k němu mu přibalí dáreček v podobě dalších souborů,
krok 3) klient parsuje soubor a teprve teď může zjistit, které soubory bude potřebovat a zjistit, jestli už jejich verzi nemá ve vyrovnávací paměti,
krok 4) klient zjistí, že některé soubory už ve vyrovnávací paměti a tedy že je není nutné posílat, tak začne odesílat požadavek na zrušení přenosu těchto přibalených souborů.
A teď moje nejasnosti:
- existuje nějaký způsob, jak může klient už při prvním požadavku zjistit, které soubory související s dotazovaným souborem nebude potřebovat? Pokud ano, jaký?
- začne server odesílat dárečkové soubory navíc okamžitě po ukončení přenosu požadovaného souboru? (tj. v okamžiku, kdy klient teprve provádí parsování přijatého souboru)
- co se stane v okamžiku, kdy server nebude respektovat požadavek na ukončení dárečkového souboru?
Server samozřejmě nebude klientovi posílat nějaké náhodné soubory, ale pošle mu ty, které bude potřebovat pro danou stránku.
Takže krok 3 je jinak – klient parsuje soubor a teprve teď by s HTTP/1.1 zjistil, které soubory bude potřebovat. Server to ale ví také, takže mu je poslal už předem.
zjistit, jestli už jejich verzi nemá ve vyrovnávací paměti
K tomuhle ale prohlížeč nepotřebuje stránku rozparsovat – nějaké soubory už mu nabídl server, a to, zda tyto soubory (v aktuální verzi) má v cache zjistí prohlížeč rovnou ze seznamu objektů cache, tu stránku k tomu vůbec nepotřebuje.
existuje nějaký způsob, jak může klient už při prvním požadavku zjistit, které soubory související s dotazovaným souborem nebude potřebovat? Pokud ano, jaký?
Při požadavku to nezjistí. S odpovědí na požadavek mu ale server nějaké soubory nabídne, klient se podívá do cache, a pokud už v ní tuhle verzi souboru má, odmítne tu nabídku serveru.
začne server odesílat dárečkové soubory navíc okamžitě po ukončení přenosu požadovaného souboru
Záleží to na prioritách, které mají ty jednotlivé soubory nastavené. Obvykle ten první soubor (HTML stránka) bude mít vyšší prioritu, takže se bude odesílat, dokud to jde, a teprve pak ty ostatní soubory. Pokud tedy půjde třeba o statickou HTML stránku, odešle se nejprve celá ta stránka a pak se hned začne s odesíláním dalších souborů (není důvod čekat). Může ale nastat i případ, že se ty další soubory začnou odesílat dřív, než se odešle celý ten první soubor – třeba je to generovaná stránka a bude se čekat na odpověď od databáze. Není důvod, aby v tu chvíli server klientovi nic neodesílal, takže začne odesílat některý z dodatečných souborů. Když pak dorazí data z databáze a vygeneruje se další kus té první HTML stránky, pozastaví se odesílání těch ostatních souborů a bude se pokračovat v odesílání té první (prioritnější) HTML stránky.
co se stane v okamžiku, kdy server nebude respektovat požadavek na ukončení dárečkového souboru?
Je to chyba implementace protokolu, klient se zachová úplně stejně, jako kdyby server nerespektoval požadavek na ukončení streamu, o který požádal klient – bude ignorovat pakety ze streamu, který je uzavřený. Pokud by klient bezpečně zjistil, že server odesílá data i po té, co dostal zprávu o resetu streamu (což je něco jiného, než že klient po resetu ještě nějaká data dostal – ta mohla být na cestě už před tím, než klient stream resetoval), mohl by asi serveru ohlásit chybu protokolu a uzavřít spojení.
A co brání serveru, aby k těm přidaným souborům přibalil dáreček úplně navíc? Klient něco takového v cache nemá a že tento dárečen není potřeba, zjistí až po rozparsování stránky.
Jenom si dovolím poznamenat, že v době generování dynamické stránky bude server obtížně posílat odpovědi v době čekání na databázi, protože kód stránky pro něj v daném okamžiku nemusí být přístupný a těžko tedy bude zkoumat její obsah - jedině, že by nastoupila predikce.
He? A proč by to server vůbec dělal? K čemu by něco takového bylo i nějaké hodně pochybné stránce? Dárečkem, co se přenese za rozumný čas, se ani to místo na disku zabrat pořádně nedá.
Proč by server neměl vědět, co má poslat? Vždyť tu stránku generuje např. nějaký php script. Takže na začátku scriptu se naplánuje přenos souborů, které ta stránka potřebuje, pak se může čekat na DB a mezitím se v jiném vlákně přenášejí ty csska a obrázky.
Proč klientovi. To je seznam souborů, které má server poslat klientovi hned aby nemusel čekat až klient _taky_ zjistí že ty soubory potřebuje a řekne si o ně.
Příklad s reálného života HTTP 1.1 :
Napíšu úřadu o formulář 15a. Úřad pošle formulář 15a. Na něm je napsané že potřebuju ještě formulář 25e. Napíšu si o formulář 25e. Na něm je, že potřebuju ...
s HTTP/2 :
Napíšu úřadu o formulář 15a. Úřad mi pošle formulář 15a a do obálky přiloží i 25e a další.
Taky příklad z reálného života: Na daňové přiznání potřebuju formulář, nazvěme ho "FA" a v některých situacích někdo bude potřebovat fiormulář "FB" a někdo jiný v jiné situaci bude potřebovat formulář "FC". Tedy "FA" je potřeba vždy a formuláře "FB" a "FC" je někdy, přičemž někdy jsou potřeba oba současně a někdy je potřeba jenom jeden z nich.
Co na to HTTP/2?
Boze ... jak v matersky. Dokud ta stranka neni na strane serveru kompletni, tak srv nemuze mit ani paru o tom, co vse je jeji soucasti. Tak maximalne muze nekde nekdo prohlasit, ze soucasti je nejaky css, ale jaky tam sou obrazky vubec netusi. A pokud se stylopis generuje taky, tak netusi ani ten.
Takze vysledkem bude zhruba to, ze misto aby srv poslal browseru html stranku, tak ji bude jeste sam parsovat aby zjistil, co k ni ma jeste pribalit ... lol.
Proč parsovat proboha? Vždyť server ví z čeho tu stránku poskládal. Tu stránku na serveru _generuje_ nějaký script. Ten script ví jaké obrázky/styly/whatever ta stránka má obsahovat a podle toho do té stránky při generování vkládá jejich jména. Takže navrch k vložení jména obrázku do stránky i okamžitě začne ten obrázek přenášet ke klientovi.
Jiste, tvle tys nebyl na netu uz nejmin 10 let, ze?
Vis jak vypada typickej soudobej web? Ze se ptam, netusis ... takovej stredne zmrvenej web se sklada ze zdroju z minimalne 5ti ruznych domen a o 1/2 toho co se zobrazi rozhoduje js.
O druhy pulce pak to, jak moc velkej paranoik je user. A v okamziku, kdy useri zjistej, ze jim servery tlacej hromady sragor, ktery stejne videt nechtej, tak budou vsechny browsery at uz z vyroby nebo pomoci pluginu tuhle uzasnou funcionalitu aktivne blokovat.
O tom, ze uz ted je bezny, ze k webu je nalinkovanejch klidne i par MB js/css/... a dalsich hovadin z cehoz se realne pouzije tak 10% ani nemluve.
Jenom si dovolím poznamenat, že v případě statických HTML stránek server nic o obsahu stránky bez parsování vědět nemůže. Pokud budu mít klasické JavaScriptové zobrazovadlo, tak jsem dokonce v situaci, že serveru nemá šanci pomoct ani statistika, a klient nemá šanci odmítnout soubory, které mu server pošle nadbytečně, protože ani sám klient netuší, které to vůbec budou (leda, že by si prováděl "předparsování" skriptu).
Ale co by se mi líbilo, kdyby si ten server předtahal vnořené stránky a soubory z jiných serverů, na které se stahovaná stránka odkazuje, a pak je pushoval klientovi :-)
Technicky v tom nebrání serveru nic, ale byl by to nesmysl, server by pouze spotřebovával prostředky na zbytečnou věc. Bylo by to stejně nesmyslné, jako přidat do HTML stránky nebo skriptu spousty dlouhých komentářů.
Zatím jsem neslyšel o implementaci server push takovým způsobem, že by server zkoumal obsah odpovědi a teprve podle toho navrhoval, které soubory nabídne. Vždy se o tom uvažuje takovým způsobem, že server pro daný požadavek má už sestavený seznam souborů, které k němu má přibalit. Ten seznam je možné připravit ručně, může ho připravit třeba redakční systém (všechny potřebné údaje typicky má k dispozici), nebo třeba Jetty má implementováno to, že sleduje referery a podle nich si sestaví seznam souborů, které prohlížeč typicky požaduje po načtení nějaké adresy (není to dokonalé, ale funguje to úplně nezávisle na odesílaných datech, server jim vůbec nemusí rozumět).
Celé HTTP2 mi trochu připadá jako přesouvání problému z jednoho místa na jiné.
Začínáme s: TCP - flow control, congestion control, multiple streams. Máme podporu v OS pro všechny tyto věci, takže cílová aplikace (web server) se tím vůbec nemusí zabývat - může být napsána nějakým způsobem multi-threadovaně a vešekeré tyhle věci pak zařizuje OS.
Bohužel to má některé nevýhody - při použití TLS trochu vyšší latence při otevření spojení (+hlavičky, které se nevejdou do jednoho TCP paketu, takže ta latence je pak ještě o trochu vyšší zvláště na mobilních sítích). Takže to řešíme tím, že celý multiplexing přesuneme do user-space a implementujeme ho znova včetně flow-control. Web server v podstatě znova implementuje celou multiplexing logiku z OS včetně flow-control, celé se to příšerně zesložití... připadá mi to takové trochu zbytečné...
Tenhle přesun věcí z kernelu do userspace se děje i jinde. Třeba vlákna. Kernelové jsou obecnější, ale když se rozumně omezená funkcionalita implementuje i v userlandu, tak je najednou přepnutí vlákna nesrovnatelně levnější záležitost. Nebo třeba databáze si ve vlastní režii dělají spoustu záležitostí kolem diskové cache, protože takhle to jde vytunit přesně pro jejich způsob využití.
To, že něco podobného dělá systém je pěkné. Ale pro přenos více souborů není třeba navazovat více tcp spojení, vyjednávat pro každé šifrovací klíč atd. HTTP dělá něco jako systém, ale v daleko omezenější míře, díky čemu to taky dokáže dělat zatraceně efektivněji.
Myslím, že thready nejsou dobrý příklad, protože user-space thready jsou obecně pro aplikaci nerozlišitelné od native threadů.
Ano, databáze si řeší někdy diskové cache samy - ale nějak si nejsem jistý, jestli je tohle krok správným směrem. Připadá mi, že problém není obecně navázání TCP spojení, problém je spíše to TLS, kterému trvá asi o 2 pakety déle, než se to s existujícími session keys dohodne. Tady mě právě trochu překvapuje snaha překopat protokol ve světě, kde se rychlost linek obecně zvyšuje, takže bude hrát menší a menší roli. Připadá mi to, jako kdyby databáze komplet implementovala cachování disku v situaci, kdy by zrychlení bylo na úrovni 5%.
To zrychlení sice závisí na aplikaci, ale 5% je hodně pesimistický odhad. Co takhle 6x tolik uživatelů na server? http://www.neotys.com/blog/performance-of-spdy-enabled-web-servers/
Rychlost linek se sice zvyšuje, ale latence zůstává +- furt na jedno brdo. A to je ta hlavní brzda ve starém HTTP.
Vypadá to tak, ale problém je spíš s terminologií, která je podobná, ale znamená jiné kroky. Flow control v TCP/IP je velmi složité, musí řešit velikosti paketů, více cest, nezaručené pořadí ap. Flow control v HTTP/2 už má všechny výhody flow control z TCP/IP (aplikace je pořád může používat), takže je velmi primitivní (má jen okno; smyslem je třeba i to, aby server nepřecpal spojení daty streamu, který se klient snaží uzavřít). Multiplexing v TCP/IP slouží pro komunikaci s více počítači, což musí složitě řešit a řídit, opět s tím, že není zaručené téměř nic, tohle ale HTTP/2 opět už využívá a tak na jeho úrovni je to zase velmi primitivní (jen ID streamu). Ten rozdíl v rychlosti vytváření streamů v HTTP/2 a v TCP/IP je právě v tom, že TCP/IP musí znovu řešit spoustu věcí, které jsou ale pro spojení se stejným klientem (tedy při znovupoužití existujícího TCP spojení) už vyřešené.
může být napsána nějakým způsobem multi-threadovaně a vešekeré tyhle věci pak zařizuje OS
Takhle jednoduše to ale moc nefunguje, webový server má nějaké zdroje, které různé požadavky nějak sdílí, a k tomu potřebuje řídit přístup, aby předcházel starvation nebo třeba backlog overflow při přílišné serializaci (oboje lze použít i pro DoS útok). Ale pokud vám to tak jednoduché stačilo, tak v HTTP/2 to můžete mít úplně stejně, nijak nenutí server vyřizovat požadavky out-of-order, jen to umožňuje.
Flow control v TCP protokolu je prakticky identické flow control v HTTP 2.0 (nic víc než okno tam není). Congestion control už samozřejmě funguje jinak... a ten smysl je spíš v tom, že pokud by na jedné straně "thread" požírající určitý stream fungoval pomalu, tak by to zablokovalo komplet celou komunikaci.
Web server pro HTTP 1.1 se dá v jazycích, které podporují "levné" thready napsat velmi elegantně. HTTP/2.0 znamená v podstatě reimplementovat celý poll() interface znovu nebo to nějak simulovat přes nějaké fronty, což asi nebude zrovna efektivní. Nebo si udělat HTTP2 -- HTTP/1.1 gateway.... a nebo to skutečně vyřizovat in-order, ale to by byl krok zpět, protože web klienti to dneska posílají paralelně ve více TCP spojeních.
Připadá mi, že web servery obecně žádné řízení prostředků nad rámec "maximum najednou vyřizovaných požadavků" nečiní, protože by musely vědět, jak dlouho se který požadavek bude vyřizovat... pletu se?
Připadá mi to celé trošku jako nástavba, která se docela snadno implementuje na klientu, docela nepříjemně špatně na serveru (obzvláště v in-process web serverech) a výsledný efekt se projeví na pár špatně připojených zařízeních přes pomalé mobilní připojení.
Flow control v TCP protokolu je prakticky identické flow control v HTTP 2.0 (nic víc než okno tam není). Congestion control už samozřejmě funguje jinak...
Nemyslel jsem přímo flow control TCP, myslel jsem obecně celý systém řízení toku, které dělá TCP/IP. Kromě congestion control v TCP je to třeba MTU discovery nebo přesměrování mobilního spojení.
Web server pro HTTP 1.1 se dá v jazycích, které podporují "levné" thready napsat velmi elegantně. HTTP/2.0 znamená v podstatě reimplementovat celý poll() interface znovu nebo to nějak simulovat přes nějaké fronty, což asi nebude zrovna efektivní. Nebo si udělat HTTP2 -- HTTP/1.1 gateway.... a nebo to skutečně vyřizovat in-order, ale to by byl krok zpět, protože web klienti to dneska posílají paralelně ve více TCP spojeních.
Není pro tyhle jazyky spíš vhodnější (Fast)CGI? Webový server napsaný v takovém jazyku pravděpodobně nebude na frontendu a interně používat HTTP (libovolnou verzi) není zrovna rychlé.
Mimochodem napsat HTTP/1.1 server tak, aby se opravdu choval podle RFC (včetně všech dost šílených případů), rozhodně není nic elegantního.
Připadá mi, že web servery obecně žádné řízení prostředků nad rámec "maximum najednou vyřizovaných požadavků" nečiní, protože by musely vědět, jak dlouho se který požadavek bude vyřizovat... pletu se?
Tohle se řeší spíš frontou, kde se požadavky od jednoho klienta prokládají požadavky od jiných klientů.
No, je to pro "velké" servery. A ty moderní (nginx, lighttpd, ...) mají jen tolik threadů, kolik je jader. Takže jim většinou postačí přejít do režimu kdy jedno http/2 spojení (tedy jeden multiplex k uživateli) bude obsluhovat nejvýše jeden thread. Ona dobře napsaná eventová smyčka je u "překydávání obsahu" z paměti(*)/backendu směrem ke klientovi rychlejší (a hlavně méně hw náročná), než multithreading.
*) V ideálním světě i z disku, ale na to je potřeba asynchronní I/O, které funguje stejně jako pipes/sockets (neblokuje). Jinak si musíme pomáhat I/O thready.
U "malých" serverů často http/2 nepotřebujete, nebo můžete zařadit http/2 gateway (ostatně podobně se používá třeba SSL gateway) - v obou případech se hodí mít tam něco jako hloupé http/1.0. (bez Connection: keep-alive, a podobných výmyslů).
A teď si představte, že Google se rozhodl jít ještě dál a obešel nedostatky TCP spojení pomocí experimentálního protokolu QUIC, což je trochu upravené SPDY běžící po udp/443. Tam se zahodila rovnou celá transportní vrstva a veškerá logika se řeší v userspace. Uvidíme, co se z toho vyvine :)
"Verze 1.1 přišla s permanentním spojením. TCP spojení se po vyřízení dotazu nezavírá, ale klient po něm může položit další dotaz. Ovšem ne před dokončením odpovědi. Pokud se zadrhla, musí klient čekat na její dokončení, než může položit další dotaz."
Je tato formulace v článku správná? Myslel jsem, že pipelining v HTTP/1.1 umožňuje položit další dotaz před dokončením předchozí odpovědi.
Máte pravdu, že HTTP/1.1 pipelining umožňuje položit dotaz ještě před příchodem odpovědi, ale používá se jen vzácně - viz http://en.wikipedia.org/wiki/HTTP_pipelining#Implementation_status Typický klient se chová popsaným způsobem.
Chápu potřebu nového protokolu, ale proč se to všechno řeší v rámci HTTP nad TCP? Polovinu požadovaných vlastností umí 15 let starý protokol SCTP, navíc přináší mnoho dalších věcí, které se v TCP emulují za cenu rozbití mnoha užitečných vlastností (SYN cookies) nebo nefungují vůbec (multihoming).
Přes Upgrade: hlavičky, jako se to dělá teď v rámci přechodu na HTTP/2. Dalo by se to řešit stejně jako u IPv6, např. jen u sítí, o kterých server ví, že to funguje, by odpovídal HTTP 101, resp. by mohl v odpovědi uvést, že se má HTTP/2 + SCTP spustit nad otevřeným TCP spojením místo otevírání nového spojení. No a časem by se z SCTP stal výchozí stav.
No jo, ale takhle upgradované TCP spojení by nebylo standardní SCTP, takže by se muselo v HTTP nadefinovat, jak to SCTP přes TCP po HTTP má vypadat. A musel by si to každý klient implementovat po svém, bez ohledu na implementaci v systému. To řešení s IPv6 se používalo pro sítě celých ISP, to vaše řešení by se muselo zabývat každou jednotlivou koncovou sítí, tedy dnes v podstatě každou IP adresou.
SCTP over UDP je definované RFC 6951, rozšířit podporu pro TCP znamená přidat pár slov do příslušného RFC, protože TCP zaručuje přinejmenším to samé co UDP. FreeBSD umí bindovat SCTP socket na existující UDP socket, u Linuxu to možná jde také, ale nezkoumal jsem.
Btw. implementaci SCTP over UDP má FF (a asi i další prohlížeče) kvůli WebRTC.
Opravdu si myslíte, že by to bylo tak jednoduché? Já odhaduji, že SCTP tunelované TCP spojením by bylo polofunkční, podobně jako je polofunkční TCP spojení tunelované TCP spojením. A pokud byste snad chtěl zasáhnout do toho spodního TCP protokolu a očesat ho tak, aby fungoval spíše jako UDP, nejspíše narazíte na myriádu rádoby transparentních middleboxů, které jakékoli vylepšení TCP protokolu nerozdýchají. Své o tom vědí třeba vývojáři Multipath-TCP.
Ty jisak, trefis se vubec do hazliku? Dost bych o tom pri tvych vedomostech pochyboval. Protoze podle tebe je logicky prisoubovat hajzl na strop a kdyz se to holt nepovede trefit, tak pochcat podlahu.
Mimochodem, widle neumej ani IPv6 (trebas dhcp) a spoustu dalsich veci, zeano. Kdypak treba pude z widli (pripadne opic) poslat (nebo i prijmout) mail s nabodenicky? Prislusny RFC uz nam plati 3 roky ... hmm.
Řekl bych, že Windows mají na implementaci kódování e-mailů v poštovních klientech asi tak stejný vliv, jako linuxové jádro - tedy vůbec žádný.
Jinak vaše komentáře jsou skutečně neuvěřitelné. Kdybyste to psal náhodně, musíte se zákonitě aspoň občas trefit, že napíšete něco správně. Fakt by mě zajímalo, jak to děláte, že jste se netrefil snad ještě ani jednou. Ale děkuji za optání, moje znalosti sítí a síťových protokolů mi nijak nebrání ve správném používání záchodu ani mi nebrání v pochopení toho, že přišroubovat záchod na strop by nebylo praktické, lepší je, když stojí na podlaze nebo je přišroubován do zdi. Takže se klidně o některé z věcí, o kterých tak rád píšete, začněte vzdělávat - nemusíte mít strach, že s tím jak budete získávat nové vědomosti, zapomenete současné návyky a třeba přestanete umět chodit na záchod. A když získáte alespoň minimum znalostí, jistě se zmenší vaše arogance a vaše komentáře budou sloužit i k něčemu jinému, než aby to pod vaším komentářem vždy někdo uváděl na pravou míru.
Dejme tomu, že máme webový server pracující pouze s HTTP/2 ať už v otevřené formě nebo https. Co to udělá, pokud na takovýto web přistoupím starším prohlížečem? Typicky mi jde třeba o MSIE na WinXP nebo i staršími verzemi Firefoxu, Chromu, Opery, .... ?
Zobrazí to aspoň nějakou chybovou hlášku?
Tak se přidám k těm co uvádějí vaše komentáře na pravou míru.
Pokud vytuhne srv, je to pouze a jenom chyba srv, zneužitelná k dos útoku. Něco takového v produkčním srv být nesmí (bavíme se o jiných počátečních bajtech spojení, které rozlišují použitý protokol, http/1.x nezná požadavek PRI. http/2.0 only musí začínat PRI...).
HTTP Klient musí rozdejchat vadnou odpověď na HTTP protokolu, nebo to (nerozdejchání) autorovi/provozovateli klienta nevadí, protože ho používá v "laboratorních" podmínkách (způsobem, kdy server nikdy špatnou odpověď nevrací).