Protokol mezi proxy a backendem

Protokol mezi proxy a backendem
« kdy: 07. 11. 2015, 21:48:32 »
Zdravím.

Řeším takovou otázku která mě možná začne trápit v blízké budoucnosti. Vzhledem k nastupujícímu trendu provozovat všude HTTP/2.0 a šifrování, řeším, jak dále vyvíjet mé backendy psané v C++. Doposud jsem používal uspořádání nginx -> proxypass -> backend(http/1.1). Je výhodné, zejména nginx řeší třeba SSL, zajišťuje jakousi izolaci, například ochranu proti různým exploitům typu slowloris, dále pak propojení statického obsahu s dynamickým a mapování cest a jinak do vlastní komunikace moc nekecá, hlavičky se předávají v zásadě 1:1, takže zbytek má v rukou sám backend.

Na co se mám připravit v případě http/2.0? Jasně, předpokládám, že nadále bude proxypass nějak emulován, takže s tím asi vydržím, ale neumím si tam představit nové featury, jako server push. Na druhou stranu mi nepřijde rozumné tu komunikaci provozovat plně na HTTP/2.0, jednak bych musel šifrovat, a pak nginx stále bude v roli míchání statického obsahu s dynamickým, takže 1:1 by to asi nešlo.

Jaké jsou další možnosti? Zkoumal jsem FastCGI, ale ten protokol mi přijde velice odporný, chybí mu jednoduchost běžného http :) Chystá se nějaká lepší alternativa?


Re:Protokol mezi proxy a backendem
« Odpověď #1 kdy: 07. 11. 2015, 21:58:44 »
Protokol HTTP/2.0 nemá povinné šifrování. Pokud mezi proxy a backendem je bezpečná síť, je to jeden z mála případů, kdy dává smysl použít nešifrované HTTP.

Jinak je samozřejmě lepší mezi proxy a backendem použít HTTP/2.0 – jednak tak můžete využít novinky HTTP/2.0 i pro komunikaci s klientem (třeba server push – je lepší to řešit na backend serveru, než přidávat logiku na proxy), jednak z toho mohou těžit i HTTP/1.1 klienti (díky server push může mít proxy server příslušný soubor už v cache, až o něj klient požádá).

Re:Protokol mezi proxy a backendem
« Odpověď #2 kdy: 08. 11. 2015, 11:40:00 »
Protokol HTTP/2.0 nemá povinné šifrování. Pokud mezi proxy a backendem je bezpečná síť, je to jeden z mála případů, kdy dává smysl použít nešifrované HTTP.

Jinak je samozřejmě lepší mezi proxy a backendem použít HTTP/2.0 – jednak tak můžete využít novinky HTTP/2.0 i pro komunikaci s klientem (třeba server push – je lepší to řešit na backend serveru, než přidávat logiku na proxy), jednak z toho mohou těžit i HTTP/1.1 klienti (díky server push může mít proxy server příslušný soubor už v cache, až o něj klient požádá).

No mě na tom nesedí jakou má to mít výhodu HTTP/2.0 je primárně multiplexovaný a optimalizovaný na přenosy po dlouhé lince a mnoha souborů naráz. Je nutné si představit, že uspořádání v serverovně asi takhle vypadat nebude. Zpravidla na každou konekci bude zároveň jedna konekce na backend a spoustu statického obsahu. Vidím tu výhodu, pokud multiplexování bude provádět proxy (nginx), která to v zásadě musí umět.

Teď jsem se díval, že W3C má nový atribut Link preload (http://w3c.github.io/preload/) i jako http hlavičku. Nginx v Http/2.0 ho umí rozpoznat a zařídit tak push. Což mi přijde jako celkem rozumný nápad - a samozřejmě to zvládne i nacachovat za předpokladu, že bych chtěl preloadovat dynamický obsah. Spíš ale vidím výhodu v preloadu statického obsahu (obrázky, styly, javascript)

Takže zatím to vypadá, že jsem si odpověděl sám.

Re:Protokol mezi proxy a backendem
« Odpověď #3 kdy: 08. 11. 2015, 12:02:35 »
Navazování nového spojení pro každý požadavek je zbytečné i v serverovně, i když je to rychlejší než od klienta k proxy serveru. Proxy server ale může mít to jedno spojení k backend serveru otevřené mnohem déle, klidně celý den. Navíc přenášet víc požadavků jedním spojením umožňoval už protokol HTTP/1.1, HTTP/2.0 k tomu přidává „jen“ paralelizaci.

Samozřejmě můžete o server push informovat proxy z backendu jinak, nějakou HTTP hlavičkou (preload je ale trochu něco jiného, i když vám třeba může stačit), ale proč to vymýšlet znova, když v protokolu HTTP/2.0 je to už vyřešené? Navíc dostupný software (např. Nginx) s těmi údaji z HTTP/2.0 bude umět pracovat, zatímco kdybyste si na to vytvářel vlastní hlavičku v HTTP/1.1, budete muset upravit i ten Nginx, aby s ní správně pracoval.

Re:Protokol mezi proxy a backendem
« Odpověď #4 kdy: 08. 11. 2015, 15:12:05 »
Navazování nového spojení pro každý požadavek je zbytečné i v serverovně, i když je to rychlejší než od klienta k proxy serveru. Proxy server ale může mít to jedno spojení k backend serveru otevřené mnohem déle, klidně celý den. Navíc přenášet víc požadavků jedním spojením umožňoval už protokol HTTP/1.1, HTTP/2.0 k tomu přidává „jen“ paralelizaci.

To už právě funguje teď i na HTTP/1.1. Samozřejmě není problém mít keepalive on a otevřeno třeba 10, 20 nebo 100 spojení... Ona ta výhoda HTTP/2.0 v paralelizaci je dost diskutabilní, a funguje jen díky praktickým, často umělým, problémům. Jinak si myslím, že TCP zvládá paralelizaci lépe. On si to uvědomuje i Google, když přichází i s UDP verzí HTTP, kdy si implementuje i celý vlastní stack. To se ukazuje, že pro rychlé HTTP se nehodí ani samotné TCP zejména díky struktuře síťové komunikace.

To že paralelizace funguje v HTTP/2.0 za to můžou dva faktory. První je umělý limit na počet HTTP/1.1 spojení per klient doména. Mám pocit, že se to ustálilo na hodnotě 2 (bývalo to i 11). Dalším problémem je slowstart na TCP při navázání nového spojení. To se děje celkem často jak prohlížeče šetří otevřené konekce.

Chtěl jsem poradit zda neexistuje jednoduché řešení spojení proxy = backend. Protože já vidím hlavní výhodu právě v proxy, která dělá SSL a tu paralelizaci z různých zdrojů poskládáných nejen ze statických souborů, ale třeba i z vícero backendů současně. Navíc dělá load balancing. Zatím jsem řešení nenašel ani na google. Nginx nabízí v zásadě jen fastcgi a proxypass. Leda si napsat vlastni modul do nginx, ale to mi prijde moc prace.