proč bych měl použít reverzní Proxy, pokud uzel.js je připravena na výrobu?
byl rok 2012. PHP a Ruby on Rails vládly jako nejvyšší serverové technologie pro vykreslování webových aplikací. Ale, odvážný nový uchazeč vzal komunitu útokem — ten, kterému se podařilo zvládnout 1M souběžných připojení. Tato technologie nebyla nikdo jiný než Node.js a od té doby neustále roste v popularitě.
Na rozdíl od většiny konkurenčních technologií té doby, Node.js přišel s vestavěným webovým serverem. Mít tento server znamenalo, že vývojáři mohli obejít nesčetné množství konfiguračních souborů, jako je php.ini
a hierarchickou sbírku.htaccess
soubory. Má vestavěný webový server, také poskytují další výhody, jako je schopnost zpracovávat soubory tak, jak byly nahrány a snadnost provádění WebSockets.
každý den uzel.webové aplikace poháněné js šťastně zpracovávají miliardy požadavků. Většina z největších společností na světě je nějakým způsobem napájena uzlem.js. Chcete-li říci, že uzel.js je připraven na výrobu je určitě
podhodnocení. Existuje však jedna rada, která platí od uzlu.vznik js: jeden by neměl přímo vystavovat uzel.js proces na webu a měl by místo toho skrýt za reverzní proxy. Ale než se podíváme na důvody, proč bychom chtěli použít reverzní proxy, podívejme se nejprve na to, co je.
reverzní proxy je v podstatě speciální typ webového serveru, který přijímá žádosti, předá je do jiného HTTP serveru někde jinde, obdrží odpověď a předá odpověď na původní žadatele.
reverzní proxy obvykle neposílá přesný požadavek. Obvykle to nějakým způsobem upraví požadavek. Například, pokud je reverzní proxy žije v www.example.org:80
, a je-předá žádostex.example.org:8080
, to bude asi přepsat původní Host
záhlaví, aby odpovídala cíl. Může také upravit požadavek jinými způsoby, jako je vyčištění poškozeného požadavku nebo překlad mezi protokoly.
jakmile reverzní proxy obdrží odpověď, může tuto odpověď nějakým způsobem přeložit. Opět platí, že běžným přístupem je upravit hlavičku Host
tak, aby odpovídala původnímu požadavku. Tělo žádostí lze také změnit. Běžnou modifikací je provedení komprese gzip na odezvě. Další běžnou změnou je povolení podpory HTTPS, pokud základní služba mluví pouze HTTP.
reverzní proxy mohou také odesílat příchozí požadavky na více instancí backendu. Pokud je služba vystavena na api.example.org
, reverzní proxy může předávat požadavky do api1.internal.example.org
api2
, atd.
existuje mnoho různých reverzní proxy tam venku. Dva z nejpopulárnějších jsou Nginx a HAProxy. Oba tyto nástroje jsou schopny provádět kompresi gzip a přidat podporu HTTPS a specializují se také na jiné oblasti. Nginx je více populární ze dvou možností, a také má některé další
prospěšných schopnostmi, jako jsou schopnost sloužit statické soubory ze souborového systému, takže to budeme používat jako příklad v tomto článku.
Nyní, když víme, co je reverzní proxy, můžeme se nyní podívat na to, proč bychom chtěli využít jeden s uzlem.js.
proč bych měl používat reverzní Proxy?
SSL ukončení je jedním z nejpopulárnějších důvodů, proč jeden používá reverzní proxy. Změna protokolu z ty aplikace od http
https
trvá trochu více práce, než připojením s
. Uzel.js sám je schopen provést potřebné šifrování a dešifrování pro https
a může být nakonfigurován tak, aby četl potřebné soubory certifikátů.
konfigurace protokolu používaného ke komunikaci s naší aplikací a správa stále vypršejících certifikátů SSL však není něco, čeho by se naše aplikace měla obávat. Kontrola certifikátů do codebase by bylo nejen zdlouhavé, ale také bezpečnostní riziko. Získání certifikátů z centrálního umístění při spuštění aplikace má také svá rizika.
z tohoto důvodu je lepší provádět SSL ukončení mimo aplikaci, obvykle v rámci reverzní proxy. Díky technologiím jako certbot
od Let ‚ s Encrypt je udržování certifikátů pomocí Nginx stejně snadné jako nastavení úlohy cron. Taková úloha může automaticky instalovat nové certifikáty a dynamicky překonfigurovat proces Nginx. Jedná se o mnohem méně rušivý proces, řekněme, restartování každého uzlu.instance aplikace js.
také tím, že umožňuje reverzní proxy provádět ukončení SSL, to znamená, že pouze kód napsaný autory reverzní proxy má přístup k vašemu soukromému certifikátu SSL. Nicméně, pokud váš uzel.aplikace js zpracovává SSL, pak každý modul třetí strany používaný vaší aplikací-dokonce i potenciálně škodlivé moduly-bude mít přístup k vašemu soukromému certifikátu SSL.
komprese gzip
komprese gzip je další funkce, kterou byste měli stáhnout z aplikace na reverzní proxy. zásady komprese gzip jsou něco, co je nejlépe nastaveno na úrovni organizace, místo toho, aby bylo nutné specifikovat a konfigurovat pro každou aplikaci.
nejlepší je použít nějakou logiku při rozhodování o tom, co gzip. Například soubory, které jsou velmi malé, možná menší než 1kb, jsou pravděpodobně nestojí za kompresi jako gzip komprimované verze někdy může být větší, nebo CPU overhead, že klient dekomprimovat soubor nemusí být stojí za to. Také při práci s binárními daty nemusí v závislosti na formátu těžit z komprese. gzip je také něco, co nelze jednoduše povolit nebo zakázat, vyžaduje zkoumání příchozí Accept-Encoding
záhlaví pro kompatibilní kompresní algoritmy.
Clustering
JavaScript je jazyk s jedním vláknem, a tedy uzel.js je tradičně serverovou platformou s jedním vláknem (i když v současné době je k dispozici podpora podprocesů experimentálního pracovníka v Node.js v10 si klade za cíl toto změnit). To znamená získat co největší propustnost z uzlu.aplikace js, jak je to možné, vyžaduje spuštění zhruba stejného počtu instancí, jako jsou jádra CPU.
uzel.js je dodáván s vestavěným modulem cluster
, který to dokáže. Příchozí požadavky HTTP budou provedeny do hlavního procesu a poté budou odeslány pracovníkům clusteru.
nicméně dynamicky škálování pracovníků clusteru by vyžadovalo určité úsilí. Při spuštění dalšího uzlu je také obvykle přidána režie.proces js jako hlavní proces dispečinku. Také procesy škálování na různých strojích je něco, co cluster
nemůže udělat.
z těchto důvodů je někdy lepší použít reverzní proxy k odeslání požadavků na běžící uzel.procesy js. Takové reverzní proxy mohou být dynamicky konfigurovány tak, aby ukazovaly na nové aplikační procesy, jakmile dorazí. Opravdu, aplikace by se měla zabývat pouze vlastní prací, neměla by se zabývat správou více kopií a odesíláním požadavků.
Enterprise Routing
Při jednání s masivní webových aplikací, jako jsou ty, postavený multi-tým podniků, to je velmi užitečné mít reverzní proxy pro určení, kde, aby předal požadavky. Například požadavek, aby example.org/search/*
mohou být směrovány na vnitřní vyhledávací aplikace, zatímco ostatní žádosti, aby example.org/profile/*
mohou být odeslány do vnitřního profilu aplikace.
takové nástroje umožňují další výkonné funkce, jako jsou sticky sessions, modré / zelené nasazení, testování A / B atd. Já osobně jsem pracoval v codebase, kde taková logika byla provedena v rámci aplikace a tento přístup způsobil, že aplikace poměrně těžké udržet.
výkonnostní výhody
uzel.js je vysoce tvárný. Je schopen obsluhovat statická aktiva ze souborového systému, provádět kompresi gzip s odpověďmi HTTP, přichází s vestavěnou podporou HTTPS a mnoha dalšími funkcemi. Má dokonce schopnost spouštět více instancí aplikace a provádět vlastní dispečink požadavků pomocí modulu cluster
.
a přesto je nakonec v našem nejlepším zájmu nechat reverzní proxy zpracovat tyto operace za nás, místo toho, aby měl náš uzel.js aplikace to udělat. Jiné než každý z výše uvedených důvodů, další důvod, proč chcete provádět tyto operace mimo uzel.js je kvůli účinnosti.
šifrování SSL a komprese GZIP jsou dvě vysoce vázané operace CPU. Vyhrazené nástroje pro reverzní proxy, jako jsou Nginx a HAProxy, obvykle provádějí tyto operace rychleji než Node.js. Mít webový server jako Nginx číst statický obsah z disku bude rychlejší než uzel.js také. Dokonce i shlukování může být někdy efektivnější, protože reverzní proxy, jako je Nginx, bude používat méně paměti a CPU než u dalšího uzlu.proces js.
ale neberte si za to naše slovo. Pojďme spustit několik měřítek!
následující zátěžové testování bylo provedeno pomocí siege
. Běželi jsme příkaz souběžnosti hodnotou 10 (10 uživatelů současně podání žádosti) a příkaz by běžet až 20,000 iterací byly provedeny (za 200 000 celkové požadavky).
pro kontrolu paměti spustíme příkaz pmap <pid> | grep total
několikrát po celou dobu životnosti benchmarku a poté výsledky zprůměrujeme. Při spuštění Nginx s jedním pracovníkem vlákno tam skončí být dvě instance běží, jeden je mistr a druhý je pracovník. Pak sečteme dvě hodnoty. Při spuštění uzlu.JS cluster of 2 budou 3 procesy, z nichž jeden je mistr a další dva jsou pracovníci. Sloupec přibližně paměti v následující tabulce je celkový součet každého Nginx a uzlu.proces js pro daný test.
Zde jsou výsledky benchmarku:
V node-cluster
měřítko používáme 2 pracovníci. To znamená, že existují 3 uzly.JS procesy běží: 1 master a 2 pracovníci. Vnginx-cluster-node
benchmark máme 2 uzly.JS procesy běží. Každý test Nginx má jeden nginx master a jeden pracovní proces Nginx. Benchmarky zahrnují čtení souboru z disku a Nginx ani Node.js byly nakonfigurovány tak, aby ukládaly soubor do paměti.
použití Nginx k provedení ukončení SSL pro uzel.výsledkem JS je zvýšení propustnosti o ~16% (749rps na 865rps). Pomocí Nginx provést gzip komprese následek propustnost představuje nárůst o ~50% (5,047 rps na 7,590 rps). Pomocí Nginx pro správu clusteru procesů vyústil ve výkonu trestu ~-1% (8,006 rps na 7,908 rps), pravděpodobně kvůli režii absolvování další žádost přes loopback síťové zařízení.
v podstatě využití paměti jednoho uzlu.proces js je ~600 MB, zatímco využití paměti procesu Nginx je kolem ~50 MB. Ty mohou trochu kolísat v závislosti na tom, jaké funkce se používají, například uzel.js používá další ~13MB při provádění ukončení SSL a Nginx používá další ~4MB při použití jako reverzní proxy verš sloužící statický obsah ze souborového systému. Zajímavostí je, že Nginx používá konzistentní množství paměti po celou dobu své životnosti. Nicméně, Uzel.js neustále kolísá kvůli povaze JavaScriptu sbírání odpadků.
zde jsou verze softwaru použitého při provádění tohoto benchmarku:
- Nginx:
1.14.2
- Node.js:
10.15.3
- Obležení:
3.0.8
testy byly prováděny na počítači s 16 gb paměti, i7-7500U CPU 4x2.70GHz
a Linux kernel 4.19.10
. Všechny potřebné soubory potřebné k obnovení výše uvedených referenčních hodnot jsou k dispozici zde:
IntrinsicLabs/nodejs-reverse-proxy-benchmarks.
Zjednodušený Kód Aplikace
Benchmarky jsou pěkné, ale podle mého názoru největší přínosy vykládání práce z Uzlu.aplikace js na reverzní proxy je aplikace jednoduchosti kódu. Dostaneme snížit počet řádků potenciálně buggy imperativního aplikačního kódu a vyměnit jej za deklarativní konfiguraci. Společné sentiment mezi vývojáři je, že jsou jistější v kódu napsané externí tým inženýrů — například Nginx, než se v kódu napsané sebe.
namísto instalace a správy kompresního middlewaru gzip a jeho udržování v aktuálním stavu v různých uzlech.js projekty můžeme místo toho nakonfigurovat na jednom místě. Místo odeslání nebo stahování certifikátů SSL a jejich opětovného získání nebo restartování aplikačních procesů můžeme místo toho použít stávající nástroje pro správu certifikátů. Namísto přidání podmíněnosti do naší aplikace zkontrolovat, zda proces je master nebo pracovník můžeme offload to do jiného nástroje.
reverzní proxy umožňuje naší aplikaci zaměřit se na obchodní logiku a zapomenout na protokoly a řízení procesů.