Hvorfor skal jeg bruke En Omvendt Proxy hvis Node.js Er Produksjonsklar?
div>
året var 2012. PHP og Ruby on Rails regjerte som de øverste server-side teknologier for gjengivelse webapplikasjoner. Men en dristig ny utfordrer tok samfunnet med storm — en som klarte Å håndtere 1m samtidige tilkoblinger. Denne teknologien var ingen ringere enn Node.js og har stadig økt i popularitet siden den gang.
I Motsetning til de fleste konkurrerende teknologier av tiden, Node.js kom med en webserver innebygd. Å ha denne serveren betydde utviklere kunne omgå en myriade av konfigurasjonsfiler som php.ini
og en hierarkisk samling av
.htaccess
filer. Å ha en innebygd webserver også gis andre bekvemmeligheter, som evnen til å behandle filer som de ble lastet opp og enkel implementering WebSockets.
Hver Dag Node.js-drevne webapplikasjoner håndterer gjerne milliarder av forespørsler. De fleste av de største selskapene i verden drives på noen måte Av Node.js. For å si Det Node.js Er Produksjonsklar er absolutt en
underdrivelse. Det er imidlertid ett råd som har vært sant siden Node.js begynnelse: man bør ikke direkte avsløre En Node.js prosess til nettet og bør i stedet skjule det bak en omvendt proxy. Men før vi ser på årsakene til at vi ønsker å bruke en omvendt proxy, la oss først se på hva man er.en omvendt proxy er i utgangspunktet en spesiell type webserver som mottar forespørsler, videresender dem til EN ANNEN HTTP-server et annet sted, mottar et svar og videresender svaret til den opprinnelige forespørselen.
en omvendt proxy sender vanligvis ikke den nøyaktige forespørselen. Vanligvis vil det endre forespørselen på noen måte. For eksempel, hvis omvendt proxy bor på www.example.org:80
, og kommer til å videresende forespørselen til
ex.example.org:8080
, vil det trolig skrive den opprinnelige Host
header å matche det av målet. Det kan også endre forespørselen på andre måter, for eksempel å rydde opp en feilformet forespørsel eller oversette mellom protokoller.
når omvendt proxy mottar et svar, kan det da oversette det svaret på en eller annen måte. Igjen, en vanlig tilnærming er å endreHost
header for å matche den opprinnelige forespørselen. Kroppen av forespørsler kan endres også. En vanlig modifikasjon er å utføre gzip-komprimering på responsen. EN annen vanlig endring er å aktivere HTTPS-støtte når den underliggende tjenesten bare snakker HTTP.
Reverse proxyer kan også sende innkommende forespørsler til flere backend forekomster. Hvis en tjeneste eksponeres ved api.example.org
, kan en omvendt proxy videresende forespørsler til api1.internal.example.org
api2
, etc.
det er mange forskjellige omvendte proxyer der ute. To av De mest populære er Nginx og HAProxy. Begge disse verktøyene kan utføre gzip-komprimering og legge TIL HTTPS-støtte, og de spesialiserer seg også på andre områder. Nginx er den mer populære av de to valgene, og har også noen andre fordelaktige evner som evnen til å betjene statiske filer fra et filsystem, så vi bruker det som et eksempel i hele denne artikkelen.Nå som vi vet hva en omvendt proxy er, kan vi nå se på hvorfor vi ønsker å gjøre bruk av En Med Node.js.
Hvorfor skal Jeg bruke En Omvendt Proxy?
SSL-oppsigelse er en av de mest populære grunnene til at man bruker en omvendt proxy. Endre protokollen for de søknad fra http
til https
tar litt mer arbeid enn å legge til en s
. Node.js selv kan utføre nødvendig kryptering og dekryptering for https
, og kan konfigureres til å lese de nødvendige sertifikatfilene.
men konfigurering av protokollen som brukes til å kommunisere med applikasjonen vår, og håndtering AV STADIG utløpende SSL-sertifikater, er egentlig ikke noe som vår søknad trenger å være bekymret for. Å sjekke sertifikater i en kodebase ville ikke bare være kjedelig, men også en sikkerhetsrisiko. Å skaffe sertifikater fra et sentralt sted ved oppstart av programmet har også sin risiko.av denne grunn er DET bedre å utføre SSL-avslutning utenfor applikasjonen, vanligvis innenfor en omvendt proxy. Takket være teknologier som certbot
ved Let ‘ S Encrypt, er det like enkelt å vedlikeholde sertifikater Med Nginx som å sette opp en cron-jobb. En slik jobb kan automatisk installere nye sertifikater og dynamisk omkonfigurere Nginx-prosessen. Dette er en mye mindre forstyrrende prosess da, si, starte hver Node.js søknad eksempel.
ved å tillate en omvendt proxy å utføre SSL-oppsigelse, betyr Dette også at bare kode skrevet av omvendt proxy-forfattere har tilgang til ditt private SSL-sertifikat. Men Hvis Noden din.js application håndterer SSL, så vil hver enkelt tredjepartsmodul som brukes av søknaden din-selv potensielt skadelige moduler-ha tilgang til ditt private SSL-sertifikat.
Gzip Komprimering
gzip komprimering er en annen funksjon som du bør avlaste fra programmet til en omvendt proxy. gzip komprimering politikk er noe best satt på et organisasjonsnivå, i stedet for å måtte spesifisere og konfigurere for hvert program.
Det er best å bruke litt logikk når du bestemmer hva du skal gzip. For eksempel filer som er svært små, kanskje mindre enn 1 kb, er sannsynligvis ikke verdt å komprimere som gzip komprimert versjon kan noen ganger være større, ELLER CPU overhead av å ha klienten dekomprimere filen kan ikke være verdt det. Også, når du arbeider med binære data, avhengig av formatet kan det ikke dra nytte av komprimering. gzip er også noe som ikke bare kan aktiveres eller deaktiveres, det krever å undersøke innkommende Accept-Encoding
header for kompatible komprimeringsalgoritmer.
Clustering
JavaScript Er et enkelttrådet språk, og følgelig Node.js har tradisjonelt vært en enkelttrådet serverplattform (selv om den for tiden eksperimentelle trådstøtten tilgjengelig i Node.js v10 tar sikte på å endre dette). Dette betyr å få så mye gjennomstrømning fra En Node.js-applikasjonen som mulig krever å kjøre omtrent samme antall forekomster som DET ER CPU-kjerner.
Node.js leveres med en innebygd cluster
modul som kan gjøre nettopp det. Innkommende HTTP-forespørsler vil bli gjort til en hovedprosess, og sendes deretter til klyngearbeidere.
dynamisk skalering av klyngearbeidere vil imidlertid ta litt innsats. Det er også vanligvis lagt overhead i å kjøre en ekstra Node.js prosessen som utsending master prosessen. Skaleringsprosesser på tvers av forskjellige maskiner er også noe som cluster
ikke kan gjøre.Av disse grunnene er det noen ganger bedre å bruke en omvendt proxy for å sende forespørsler til kjørende Node.js prosesser. Slike omvendte proxyer kan konfigureres dynamisk for å peke på nye applikasjonsprosesser når de kommer. Egentlig bør en søknad bare være opptatt av å gjøre sitt eget arbeid, det bør ikke være opptatt av å administrere flere kopier og sende forespørsler.
Enterprise Routing
når du arbeider med massive webapplikasjoner, for eksempel de som er bygget av multi-team bedrifter, er det veldig nyttig å ha en omvendt proxy for å bestemme hvor du skal videresende forespørsler til. For eksempel kan forespørsler til example.org/search/*
rutes til det interne søkeprogrammet, mens andre forespørsler til example.org/profile/*
kan sendes til det interne profilprogrammet.
Slike verktøy tillater andre kraftige funksjoner som klissete økter, Blå / Grønne distribusjoner, A/B-testing, etc. Jeg har personlig jobbet i en kodebase hvor slik logikk ble utført i søknaden, og denne tilnærmingen gjorde søknaden ganske vanskelig å vedlikeholde.
Ytelsesfordeler
Node.js er svært formbar. Det er i stand til å betjene statiske eiendeler fra et filsystem, utføre gzip-komprimering MED HTTP-svar, kommer med innebygd støtte FOR HTTPS, og mange andre funksjoner. Den har til og med muligheten til å kjøre flere forekomster av et program og utføre sin egen forespørsel, ved hjelp av modulencluster
.Og likevel er det i vår beste interesse å la en omvendt proxy håndtere disse operasjonene for oss, i stedet for å ha Vår Node.js søknad gjør det. Annet enn hver av grunnene nevnt ovenfor, en annen grunn til å ville gjøre disse operasjonene utenfor Node.js skyldes effektivitet.
SSL-kryptering og gzip-komprimering er to SVÆRT CPU-bundet operasjoner. Dedikerte omvendt proxy-verktøy, Som Nginx og HAProxy, utfører vanligvis disse operasjonene raskere enn Node.js. Å ha En webserver som Nginx lese statisk innhold fra disk kommer til å være raskere Enn Node.js også. Selv clustering kan noen ganger være mer effektiv som en omvendt proxy som Nginx vil bruke mindre minne og CPU enn en ekstra Node.js prosess.
men ikke ta vårt ord for det. La oss kjøre noen benchmarks!
følgende belastningstesting ble utført med siege
. Vi kjørte kommandoen med en samtidighetsverdi på 10 (10 samtidige brukere som gjorde en forespørsel) og kommandoen ville løpe til 20.000 iterasjoner ble gjort(for 200.000 generelle forespørsler).
for å sjekke minnet kjører vi kommandoen pmap <pid> | grep total
et par ganger i løpet av benchmarkens levetid, og gjennomsnittlig resultatene. Når Du kjører Nginx med en enkelt arbeidstråd, blir det to tilfeller som kjører, en er mesteren og den andre er arbeideren. Vi summerer deretter de to verdiene. Når du kjører En Node.js cluster of 2 det vil være 3 prosesser, en er master og de to andre er arbeidere. Den ca. minnekolonnen i tabellen nedenfor er en total sum Av Hver Nginx og Node.js prosess for den gitte testen.
her er resultatene av referansen:
i node-cluster
benchmark bruker vi 2 arbeidere. Dette betyr at det er 3 Noder.js prosesser som kjører: 1 master og 2 arbeidere. Inginx-cluster-node
benchmark har vi 2 Node.js prosesser kjører. Hver Nginx-test har en Enkelt Nginx-mester og en Enkelt Nginx-arbeidsprosess. Benchmarks innebærer å lese en fil fra disk, og Verken Nginx eller Node.js ble konfigurert til å cache filen i minnet.
Bruke Nginx til å utføre SSL-avslutning for Node.js resulterer i en gjennomstrømmingsøkning på ~16% (749rps til 865rps). Bruke Nginx til å utføre gzip-komprimering resulterer i en gjennomstrømningsøkning på ~50% (5,047 rps til 7,590 rps). Bruk Av Nginx til å administrere en klynge av prosesser resulterte i en ytelsesstraff på ~-1% (8,006 rps til 7,908 rps), sannsynligvis på grunn av overhead av å sende en ekstra forespørsel over loopback nettverksenheten.
I Hovedsak minnebruk av en Enkelt Node.js-prosessen er ~600mb, mens minnebruken til En Nginx-prosess er rundt ~50MB. Disse kan variere litt avhengig av hvilke funksjoner som brukes, for Eksempel Node.js bruker en ekstra ~13mb når DU utfører SSL-avslutning, Og Nginx bruker en ekstra ~4MB når den brukes som et omvendt proxy-vers som serverer statisk innhold fra filsystemet. En interessant ting å merke seg er At Nginx bruker en konsekvent mengde minne gjennom hele levetiden. Men Node.js svinger stadig på grunn Av Søppel-samle natur JavaScript.
her er versjonene av programvaren som brukes mens du utfører denne referansen:
- Nginx:
1.14.2
- Node.js:
10.15.3
- Siege:
3.0.8
testene ble utført på en maskin MED 16 GB minne, eni7-7500U CPU 4x2.70GHz
Og Linux-kjernen4.19.10
. Alle nødvendige filer som kreves for å gjenskape de ovennevnte benchmarks er tilgjengelige her:
IntrinsicLabs / nodejs-reverse-proxy-benchmarks.
Forenklet Programkode
Benchmarks er fine og alle, men etter min mening er de største fordelene med å avlaste arbeid fra En Node.js søknad til en omvendt proxy er at av kode enkelhet. Vi kommer til å redusere antall linjer med potensielt buggy imperativ programkode og bytte den til deklarativ konfigurasjon. En vanlig følelse blant utviklere er at de er mer sikre på kode skrevet av et eksternt team av ingeniører — som Nginx — enn i kode skrevet av seg selv.I Stedet for å installere og administrere gzip komprimering mellomvare og holde det up-to-date på tvers av Ulike Node.js prosjekter vi kan i stedet konfigurere den på ett sted. I stedet for å sende ELLER laste NED SSL-sertifikater og enten hente DEM på nytt eller starte søknadsprosesser på nytt, kan vi i stedet bruke eksisterende sertifikatadministrasjonsverktøy. I stedet for å legge conditionals til vår søknad for å sjekke om en prosess er en mester eller arbeidstaker vi kan avlaste dette til et annet verktøy.en omvendt proxy gjør at søknaden vår kan fokusere på forretningslogikk og glemme protokoller og prosessledelse.