Vlákno názorů k článku Jak funguje nový protokol HTTP/2 od andy - Celé HTTP2 mi trochu připadá jako přesouvání problému...

  • Článek je starý, nové názory již nelze přidávat.
  • 4. 3. 2015 10:38

    andy (neregistrovaný)

    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é...

  • 4. 3. 2015 12:13

    JSH (neregistrovaný)

    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.

  • 4. 3. 2015 13:31

    andy (neregistrovaný)

    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%.

  • 4. 3. 2015 14:01

    JSH (neregistrovaný)

    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.

  • 4. 3. 2015 12:21

    Sten (neregistrovaný)

    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.

  • 4. 3. 2015 13:50

    andy (neregistrovaný)

    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í.

  • 4. 3. 2015 15:32

    Sten (neregistrovaný)

    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ů.

  • 4. 3. 2015 15:49

    Ondřej Novák

    Je fakt, že tam kde používáme na část požadavku proxy_pass se to asi nebude řešit nějak elegantně. Proxy_passovat http/2.0 si nedokážu dost dobře představit (už jen proto, že nginx zpravidla vyřizuje statické objekty). Kromě FastCGI jiný vhodný protokol k backendu nevidím.

  • 5. 3. 2015 17:23

    ebik (neregistrovaný)

    No a u fastcgi existuje jeho rozšíření na "asynchronní" variantu, kdy se multiplexují i komunikace s fastcgi serverem. Tam vidím naopak výhodu, že server, který překládá http/2 na afcgi nemusí držet tolik otevřených spojení.

  • 5. 3. 2015 17:19

    ebik (neregistrovaný)

    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ů).

  • 5. 3. 2015 10:14

    Ondřej Caletka
    Zlatý podporovatel

    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 :)

  • 5. 3. 2015 16:18

    Ivan (neregistrovaný)

    Microsoft sel svoji cestou. IE posila http hlavicku requestu primo v SYN packetu a ve spolupraci s IIS dokaze dohadovani TCP spojeni obejit uplne.