hvorfor skal jeg bruge en omvendt fuldmagt, hvis Node.js er produktionsklar?
året 2012. PHP og Ruby on Rails regerede som de øverste server-side teknologier til rendering internet applikationer. Men, en dristig ny udfordrer tog samfundet med storm — en, der formåede at håndtere 1m samtidige forbindelser. Denne teknologi var ingen anden end Node.js og er støt steget i popularitet lige siden.
I modsætning til de fleste konkurrerende teknologier af tiden, Node.js kom med en indbygget internetserver. Under denne server betød udviklere kunne omgå et utal af konfigurationsfiler såsom php.ini
og en hierarkisk samling af.htaccess
filer. At have en indbygget internetserver gav også andre bekvemmeligheder, som evnen til at behandle filer, da de blev uploadet, og den lette implementering af internetadresser.
hver dag Node.js-drevne internetapplikationer håndterer heldigvis milliarder af anmodninger. De fleste af de største virksomheder i verden drives på en eller anden måde af Node.js. At sige den knude.js er produktionsklar er bestemt en
underdrivelse. Der er dog et råd, der har været sandt siden Node.JS ‘ s start: man bør ikke direkte udsætte en Node.JS proces til internettet og bør i stedet skjule det bag en omvendt fuldmagt. Men før vi ser på grundene til, at vi ønsker at bruge en omvendt fuldmagt, lad os først se på, hvad man er.
en omvendt fuldmagt er dybest set en speciel type internetserver, der modtager anmodninger, videresender dem til en anden HTTP-server et andet sted, modtager et svar og videresender svaret til den oprindelige anmoder.
en omvendt fuldmagt sender normalt ikke den nøjagtige anmodning. Typisk vil det ændre anmodningen på en eller anden måde. For eksempel, hvis den omvendte fuldmagt lever på www.example.org:80
, og vil videresende anmodningen tilex.example.org:8080
, vil den sandsynligvis omskrive den oprindelige Host
header for at matche målet. Det kan også ændre anmodningen på andre måder, såsom at rydde op i en misdannet anmodning eller oversætte mellem protokoller.
når den omvendte fuldmagt modtager et svar, kan den derefter oversætte dette svar på en eller anden måde. Igen er en fælles tilgang at ændreHost
header for at matche den oprindelige anmodning. Anmodningernes krop kan også ændres. En almindelig ændring er at udføre gsip-komprimering på responsen. En anden almindelig ændring er at aktivere HTTPS-support, når den underliggende tjeneste kun taler HTTP.
omvendte fuldmagter kan også sende indgående anmodninger til flere backend-forekomster. Hvis en tjeneste udsættes for api.example.org
, kan en omvendt fuldmagt videresende anmodninger til api1.internal.example.org
api2
osv.
der er mange forskellige omvendte fuldmagter derude. To af de mest populære er Nginka og Haproksy. Begge disse værktøjer er i stand til at udføre gcip-komprimering og tilføje HTTPS-support, og de er også specialiserede inden for andre områder. Ngink er den mere populære af de to valg, og har også nogle andre
gavnlige funktioner såsom evnen til at tjene statiske filer fra et filsystem, så vi vil bruge det som et eksempel i hele denne artikel.
nu hvor vi ved, hvad en omvendt fuldmagt er, kan vi nu undersøge, hvorfor vi gerne vil bruge en med Node.js.
hvorfor skal jeg bruge en omvendt fuldmagt?
SSL-opsigelse er en af de mest populære grunde til, at man bruger en omvendt fuldmagt. Ændring af protokollen for en applikation fra http
til https
tager lidt mere arbejde end at tilføje en s
. Knudepunkt.js selv er i stand til at udføre den nødvendige kryptering og dekryptering for https
og kan konfigureres til at læse de nødvendige certifikatfiler.
konfiguration af protokollen, der bruges til at kommunikere med vores applikation, og styring af stadig udløbne SSL-certifikater, er imidlertid ikke rigtig noget, som vores applikation skal være bekymret for. Kontrol af certifikater i en kodebase ville ikke kun være kedelig, men også en sikkerhedsrisiko. Erhvervelse af certifikater fra en central placering ved applikationsstart har også sine risici.
af denne grund er det bedre at udføre SSL-opsigelse uden for applikationen, normalt inden for en omvendt fuldmagt. Takket være teknologier som certbot
af Let ‘ s Encrypt er det lige så nemt at vedligeholde certifikater som at oprette et cron-job. Et sådant job kan automatisk installere nye certifikater og dynamisk omkonfigurere Nginks-processen. Dette er en meget mindre forstyrrende proces, så sig genstart af hver Node.JS ansøgning instans.
Ved at tillade en omvendt fuldmagt til at udføre SSL-opsigelse betyder det også, at kun kode skrevet af de omvendte fuldmægtige forfattere har adgang til dit private SSL-certifikat. Men hvis din Node.js-applikationen håndterer SSL, så har hvert enkelt tredjepartsmodul, der bruges af din applikation — selv potentielt ondsindede moduler — adgang til dit private SSL-certifikat.
Gsip-komprimering
gsip-komprimering er en anden funktion, som du skal aflaste fra applikationen til en omvendt fuldmagt. gcip-komprimeringspolitikker er noget, der bedst indstilles på organisationsniveau, i stedet for at skulle specificere og konfigurere for hver applikation.
det er bedst at bruge en vis logik, når man beslutter, hvad man skal sippe. For eksempel er filer, der er meget små, måske mindre end 1 kB, sandsynligvis ikke værd at komprimere, da den komprimerede version af gcip undertiden kan være større, eller CPU-overhead for at få klienten til at dekomprimere filen er muligvis ikke det værd. Også, når der beskæftiger sig med binære data, afhængigt af formatet kan det ikke drage fordel af komprimering. det kræver at undersøge den indgåendeAccept-Encoding
header for kompatible komprimeringsalgoritmer.
Clustering
JavaScript er et enkelttrådet sprog og dermed Node.js har traditionelt været en enkelttrådet serverplatform (dog den aktuelt eksperimentelle arbejdstrådstøtte, der er tilgængelig i Node.js v10 sigter mod at ændre dette). Dette betyder at få så meget gennemstrømning fra en Node.js ansøgning som muligt kræver at køre omtrent det samme antal forekomster, som der er CPU-kerner.
Node.js leveres med et indbyggetcluster
modul, der kan gøre netop det. Indgående HTTP-anmodninger sendes til en masterproces og sendes derefter til klyngearbejdere.
imidlertid ville dynamisk skalering af klyngearbejdere tage en vis indsats. Der er også normalt tilføjet overhead i at køre en ekstra Node.js-processen som afsendelsesmasterprocessen. Skaleringsprocesser på tværs af forskellige maskiner er også noget, som cluster
ikke kan gøre.
af disse grunde er det nogle gange bedre at bruge en omvendt fuldmagt til at sende anmodninger til kørende Node.JS processer. Sådanne omvendte fuldmagter kan konfigureres dynamisk til at pege på nye applikationsprocesser, når de ankommer. Virkelig, en ansøgning skal bare være bekymret for at gøre sit eget arbejde, det bør ikke være bekymret for at styre flere kopier og afsendelse af anmodninger.
Enterprise Routing
når man beskæftiger sig med massive internetapplikationer, som dem, der er bygget af multi-team virksomheder, er det meget nyttigt at have en omvendt fuldmagt til at bestemme, hvor man skal videresende anmodninger til. For eksempel kan anmodninger til example.org/search/*
dirigeres til det interne søgeprogram, mens andre anmodninger til example.org/profile/*
kan sendes til det interne profilprogram.
sådan værktøj giver mulighed for andre kraftfulde funktioner såsom klæbrige sessioner, blå/grønne implementeringer, A/B-test osv. Jeg har personligt arbejdet i en kodebase, hvor en sådan logik blev udført i applikationen, og denne tilgang gjorde applikationen ret vanskelig at vedligeholde.
ydelsesfordele
Node.js er meget formbar. Det er i stand til at betjene statiske aktiver fra et filsystem, udføre gcip-komprimering med HTTP-svar, leveres med indbygget support til HTTPS og mange andre funktioner. Det har endda evnen til at køre flere forekomster af et program og udføre sin egen anmodning afsendelse, ved hjælp af cluster
modul.
og alligevel er det i sidste ende i vores bedste interesse at lade en omvendt fuldmagt håndtere disse operationer for os i stedet for at have vores Node.js ansøgning gør det. Andre end hver af de grunde, der er anført ovenfor, en anden grund til at ville gøre disse operationer uden for Node.js skyldes effektivitet.SSL-kryptering og gsip-komprimering er to meget CPU-bundne operationer. Dedikerede værktøjer til omvendt fuldmagt, som f.eks.js. At have en internetserver som
men tag ikke vores ord for det. Lad os køre nogle benchmarks!
følgende belastningstest blev udført under anvendelse afsiege
. Vi kørte kommandoen med en samtidighedsværdi på 10 (10 samtidige brugere, der fremsætter en anmodning), og kommandoen ville køre, indtil der blev foretaget 20.000 iterationer (for 200.000 samlede anmodninger).
for at kontrollere hukommelsen kører vi kommandoen pmap <pid> | grep total
et par gange i løbet af benchmarkets levetid, så gennemsnit resultaterne. Når man kører med en enkelt arbejdstråd, bliver der to tilfælde, der kører, den ene er mesteren og den anden er arbejderen. Vi opsummerer derefter de to værdier. Når du kører en Node.js klynge af 2 der vil være 3 processer, den ene er mesteren og de to andre er arbejdere. Kolonnen ca. hukommelse i den følgende tabel er en samlet sum af hver node og Node.JS proces for den givne test.
Her er resultaterne af benchmarket:
i node-cluster
benchmark vi bruger 2 arbejdere. Det betyder, at der er 3 Node.js processer kører: 1 master og 2 arbejdere. Inginx-cluster-node
benchmark har vi 2 Node.JS processer kører. Hver test har en enkelt master og en enkelt proces. Benchmarks indebærer at læse en fil fra disken, og hverken node eller node.js blev konfigureret til at cache filen i hukommelsen.
brug af node til at udføre SSL-opsigelse.js resulterer i en stigning i gennemstrømningen på ~16% (749rps til 865rps). Brug af Ngink til at udføre kompression resulterer i en stigning i gennemstrømningen på ~50% (5.047 rps til 7.590 rps). Brug af Ngink til at styre en klynge af processer resulterede i en ydelsesstraf på ~-1% (8.006 rps til 7.908 rps), sandsynligvis på grund af omkostningerne ved at sende en yderligere anmodning over loopback-netværksenheden.
i det væsentlige hukommelsesforbruget af en enkelt Node.js-processen er ~600 MB, mens hukommelsesforbruget af en Nginks-proces er omkring ~50 MB. Disse kan svinge lidt afhængigt af hvilke funktioner der bruges, for eksempel Node.js bruger en ekstra ~13MB, når du udfører SSL-opsigelse, og Nginks bruger en ekstra ~4MB, når den bruges som et omvendt fuldmægtigvers, der serverer statisk indhold fra filsystemet. En interessant ting at bemærke er, at Nginks bruger en ensartet mængde hukommelse i hele sin levetid. Dog Node.js svinger konstant på grund af JavaScript ‘ s affaldsindsamlende karakter.
Her er de versioner af programmet, der bruges under udførelsen af denne benchmark:
- Ngink:
1.14.2
- Node.js:
10.15.3
- Siege:
3.0.8
testene blev udført på en maskine med 16 GB hukommelse, en i7-7500U CPU 4x2.70GHz
og Linuks kerne 4.19.10
. Alle de nødvendige filer, der kræves for at genskabe ovenstående benchmarks, er tilgængelige her:
IntrinsicLabs/nodejs-reverse-fuldmægtig-benchmarks.
forenklet applikationskode
Benchmarks er gode og alle, men efter min mening er de største fordele ved at aflæse arbejde fra en Node.js ansøgning til en omvendt fuldmagt er, at kode enkelhed. Vi kommer til at reducere antallet af linjer med potentielt buggy imperativ applikationskode og bytte den til deklarativ konfiguration. En fælles følelse blandt udviklere er, at de er mere sikre på kode skrevet af et eksternt team af ingeniører — som f.eks.
i stedet for at installere og administrere gcip-komprimeringsmiddel og holde det opdateret på tværs af forskellige knudepunkter.js-projekter kan vi i stedet konfigurere det på et enkelt sted. I stedet for at sende eller hente SSL-certifikater og enten genanvende dem eller genstarte applikationsprocesser kan vi i stedet bruge eksisterende certifikatstyringsværktøjer. I stedet for at tilføje betingelser til vores applikation for at kontrollere, om en proces er en mester eller arbejdstager, kan vi aflaste dette til et andet værktøj.
en omvendt fuldmagt giver vores applikation mulighed for at fokusere på forretningslogik og glemme protokoller og processtyring.