Uvod
Nginx je web poslužitelj visokih performansi koji se također koristi kao reverzni proxy, mail proxy, sustav za uravnoteženje opterećenja i HTTP predmemorija. Nginx je besplatan i otvorenog koda, što omogućuje svakome da ga preuzme i koristi u svom poslužiteljskom okruženju.
Možda ste već koristili Nginx za posluživanje web stranica. U ovom vodiču raspravljat ćemo o drugim mogućnostima Nginxa. HTTP proksiranje mogućnost Nginxa omogućuje mu prosljeđivanje zahtjeva pozadinskim HTTP poslužiteljima na obradu. S ovom značajkom možete postaviti više pozadinskih poslužitelja. To vam omogućuje da skalirate svoju infrastrukturu prema potrebi kako biste se nosili s naglim porastima zahtjeva klijenata.
Kako budemo napredovali kroz vodič, naučit ćete o skaliranju vaše infrastrukture pomoću Nginxovih uravnoteženja opterećenja svojstava, međuspremanja, i predmemoriranja odgovora kako biste poboljšali performanse svog poslužitelja, kao i osigurali bolje iskustvo za klijente. Počnimo!
Prije svega, kako biste započeli s Nginxom, pogledajte naš vodič o tome kako instalirati Nginx na vaš Ubuntu poslužitelj.
Opće informacije o proksiranju
Ako se vaše znanje o web poslužiteljima svodi samo na obradu zahtjeva za web stranice i posluživanje web stranica, možda se pitate zašto moramo proksirati zahtjeve. U nastavku ćemo objasniti razloge za to.
Jedan od razloga za proksiranje zahtjeva s Nginxa na druge poslužitelje je podrška skalabilnosti vaše infrastrukture. Nginx prema zadanim postavkama istovremeno obrađuje mnogo veza. To ga čini savršenim kao prvu točku kontakta za klijente. Zatim može proslijediti zahtjeve raznim pozadinskim poslužiteljima kako bi obradili stvarne zahtjeve klijenata. To je ono što raspoređuje opterećenje. Stoga osigurava da možete skalirati svoju infrastrukturu što je više moguće. Također vam omogućuje da isključite druge poslužitelje radi održavanja dok ostali nastavljaju posluživati zahtjeve.
Drugi razlog zašto biste mogli htjeti proksirati zahtjeve na druge poslužitelje je kada koristite aplikacijske poslužitelje koji nisu prikladni za izravno rukovanje zahtjevima klijenata u produkcijskim okruženjima uživo. Nekoliko okvira, uključujući web poslužitelje, nije prikladno za visoke performanse poput Nginxa. Dopuštanje Ngincu da bude ulazna točka i proksira zahtjeve ovim poslužiteljima s lošijim performansama može osigurati bolje iskustvo vašim korisnicima. Osim toga, može jamčiti povećanu sigurnost za vašu aplikaciju.
Proces proksiranja zahtjeva u Ngincu uključuje manipuliranje zahtjevom s Nginx poslužitelja i njegovo prosljeđivanje drugim pozadinskim poslužiteljima na stvarnu obradu. Nakon što drugi pozadinski poslužitelji obrade zahtjev, vraćaju rezultat Ngincu. On zatim šalje rezultat kao odgovor klijentu. Klijent je u ovom slučaju web preglednik ili čak mobilna web aplikacija. Ostali pozadinski poslužitelji mogu biti lokalni poslužitelji koji nisu javno dostupni na internetu, udaljeni poslužitelji ili čak drugi virtualni poslužitelji unutar konfiguracija Nginx blokova poslužitelja. Ti drugi poslužitelji kojima Nginx proksira zahtjeve nazivaju se uzvodni poslužitelji.
Nginx može proksirati zahtjeve poslužiteljima koji komuniciraju pomoću nekoliko protokola uključujući HTTP(S), Memcached, SCGI, FastCGI, i uWSGI. Za svaku vrstu protokola postoje skupovi direktiva. Naš fokus u ovom vodiču je HTTP protokol. Nginx raščlanjuje zahtjeve i komponente poruka u format koji uzvodni poslužitelj može protumačiti i obraditi.
Analiza osnovnog HTTP prosljeđivanja proxyja
Najjednostavnija vrsta proxyja uključuje prosljeđivanje zahtjeva jednom poslužitelju koji komunicira putem HTTP-a. Ova vrsta proxyja općenito se naziva „proxy pass” i njome upravlja prikladno nazvana direktiva proxy_pass unutar Nginx konfiguracijskih datoteka.
Direktiva proxy_pass pojavljuje se unutar lokacijskih blokova. Također se nalazi unutar blokova lokacijskog konteksta i u limit_except kontekstima. Kada se zahtjev podudara s lokacijom koja sadrži direktivu proxy_pass, zahtjev ide na URL koji direktiva specificira. Ispod je primjer isječka konfiguracije:
|
1 2 3 4 |
listen 80; location / { proxy_pass http://127.0.0.1:3000; } |

U gornjem primjeru, zahtjevi prema portu 80 išli bi na localhost:3000:

Gornja snimka zaslona prikazuje zadanu Nginx stranicu kada pokušate pristupiti localhostu. Nakon ponovnog pokretanja Nginx poslužitelja s aktivnom direktivom proxy pass, svi zahtjevi ići će na port 3000. Demo aplikacija se izvodi na portu 3000, što možete vidjeti na slici ispod, a možete joj pristupiti izravno s localhosta bez navođenja porta:

U sljedećem primjeru nije naveden URI na kraju poslužitelja u definiciji proxy_pass. Za definicije koje odgovaraju ovom uzorku, URI koji klijent zahtijeva bit će proslijeđen uzvodnom poslužitelju onakav kakav jest.
|
1 2 3 |
lokacija /podudaranje/url/ovdje { proxy_pass http://example.com; } |
Na primjer, kada ovaj blok obrađuje zahtjev za /match/url/here, URI zahtjeva ići će na poslužitelj example.com kao http://example.com/match/url/here.
Ispod je primjer alternativnog isječka konfiguracije:
|
1 2 3 |
lokacija /podudaranje/url/ovdje { proxy_pass http://example.com/new/url/prefix; } |
Kao što možete vidjeti u gornjem isječku, definirali smo URI segment na kraju proxy poslužitelja kao new/url/prefix. Kada definirate URI u definiciji proxy_pass, dio zahtjeva koji se podudara s definicijom lokacije zamjenjuje se ovim URI-jem prilikom odlaska na uzvodni poslužitelj radi obrade.
Na primjer, zahtjev za /match/url/here na Nginx poslužitelju prosljeđuje se uzvodnom poslužitelju kao http://example.com/new/url/here. /match/url se zamjenjuje s /new/url. Imajte to na umu.
U nekim slučajevima prosljeđivanje URI-ja kao što je gore opisano nije moguće. U takvim slučajevima Nginx zanemaruje URI na kraju definicije proxy_pass. Na kraju se uzvodnom poslužitelju prosljeđuje ili izvorni URI od klijenta ili URI koji modificiraju druge direktive.
Primjer je kada se regularni izrazi podudaraju s lokacijom. Nginx možda neće moći odrediti koji se dio URI-ja podudarao s izrazom. Stoga šalje izvorni URI zahtjeva klijenta. To uzrokuje prepisivanje i rukovanje klijentskim URI-jem u istom bloku. U takvom slučaju prosljeđuje se prepisani URI.
Kako Nginx obrađuje zaglavlja?
Zaglavlja su ključna za način na koji poslužitelj obrađuje zahtjev. Neka zaglavlja mogu sadržavati informacije o autentifikaciji. Stoga moramo razumjeti kako će Nginx proxyiranje obraditi zaglavlja. Proxy zahtjev od Nginxa prema uzvodnom poslužitelju izgledat će drugačije od onog koji je došao izravno od klijenta. Neke od razlika rezultat su zaglavlja koja idu uz proxy zahtjev.
Tijekom proxyiranja zahtjeva, Nginx će prilagoditi zaglavlja zahtjeva koja prima od klijenta. Neke od tih prilagodbi uključuju:
-
Uklanjanje svih praznih zaglavlja. Prazna zaglavlja samo napuhuju zahtjev, pa ih nema smisla prosljeđivati uzvodnom poslužitelju.
-
Sva zaglavlja koja sadrže podvlake prema zadanim se postavkama smatraju nevažećima, pa se stoga uklanjaju iz zahtjeva. Ako želite promijeniti ovo ponašanje i dopustiti Nginxu da zaglavlja s podvlakama tumači kao važeća, tada možete postaviti direktivu underscores_in_headers na „on”. Ako to ne učinite, takva zaglavlja od klijenta nikada neće doći do uzvodnog poslužitelja.
-
Zaglavlje „Host” prepisuje se u vrijednost određenu varijablom $proxy_host. To je IP adresa ili naziv i broj porta uzvodnog poslužitelja, kako je određeno direktivom proxy_pass.
-
Vrijednost zaglavlja „Connection” mijenja se u „close”. Zaglavlje veze sadrži informacije o određenoj vezi uspostavljenoj između dviju strana. Kada Nginx postavi njegovu vrijednost na close, to uzvodnom poslužitelju signalizira da će se veza zatvoriti nakon što se odgovori na izvorni zahtjev, pa stoga ne bi trebao očekivati da će to biti trajna veza.
Evo nekoliko točaka koje možemo uočiti iz gore navedenih prilagodbi zaglavlja proxy zahtjeva:
-
Ako ne želite da se zaglavlje proslijedi uzvodnom poslužitelju, postavljanje na prazan niz potpuno će ga ukloniti iz zahtjeva.
-
Ako će aplikacija na vašem uzvodnom poslužitelju obrađivati nestandardna zaglavlja, osigurajte da zaglavlja nemaju podvlaku. Opcionalno, možete postaviti direktivu underscores_in_headers na „on” u svojoj konfiguraciji (vrijedi ili u kontekstu zadane deklaracije poslužitelja za kombinaciju IP adrese/porta ili u HTTP kontekstu). To će osigurati da zaglavlja ne budu označena kao nevažeća i da će stoga doista biti proslijeđena uzvodnom poslužitelju.
-
Zaglavlje „Host” prilično je važno u većini situacija proxyiranja. Prema zadanim postavkama postavljeno je na vrijednost $proxy_host, varijablu koja sadrži naziv domene ili IP adresu i port preuzete iz specifikacije proxy_pass. Ova se adresa odabire prema zadanim postavkama i povlači izravno iz informacija o vezi. To je jedina adresa za koju Nginx ima jamstvo da će uzvodni poslužitelj na nju odgovoriti.
Ispod su najčešće vrijednosti za zaglavlje „Host”:
-
$host – varijabla se postavlja prema redoslijedu prvenstva na naziv računala iz samog retka zahtjeva, zaglavlje „Host” iz zahtjeva klijenta ili naziv poslužitelja koji odgovara zahtjevu.
-
$http_host – varijabla koja postavlja zaglavlje „Host” na zaglavlje „Host” iz zahtjeva klijenta. Zaglavlja u klijentovom zahtjevu uvijek su dostupna Nginxu kao varijable. Te varijable počinju s prefiksom $http_, a zatim slijedi naziv zaglavlja malim slovima. Iako će varijabla $http_host uglavnom raditi dobro, kada zahtjevu klijenta nedostaje važeće zaglavlje „Host”, to može dovesti do neuspjeha prosljeđivanja.
-
$proxy_host – varijabla koja postavlja zaglavlje „Host” na kombinaciju naziva domene ili IP adrese i porta preuzetu iz specifikacije proxy_pass. To je zadano ponašanje s gledišta Nginxa i stoga se smatra sigurnim. Međutim, to možda nije ono što je poslužitelju potrebno za ispravnu obradu zahtjeva.
Većina konfiguracija uključivat će postavljanje zaglavlja „Host” na varijablu $host. Vrlo je fleksibilna i pružit će točno popunjena zaglavlja uzvodnom poslužitelju.
Postavljanje i izmjena zaglavlja
Direktiva proxy_set_header omogućuje nam postavljanje ili izmjenu zaglavlja za proxy veze. U ranije spomenutom zaglavlju „Host”, možemo učiniti sljedeće kako bismo izmijenili i dodali dodatna zaglavlja uobičajena za proxyirane zahtjeve:
|
1 2 3 4 5 6 7 8 |
location /podudaranje/ovdje { proxy_set_header HOST $host; proxy_set_header X-Forwarded-Proto $schema; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_pass http://example.com/new/prefix; } |
U gornjem isječku konfiguracije postavljamo zaglavlje „Host” na varijablu $host koja sadrži informacije o izvornom računalu koje se traži. Postavljamo zaglavlje X-Forwarded-Proto s informacijama o shemi izvornog zahtjeva klijenta (to može biti HTTP ili HTTPS zahtjev).
Stvarnu IP adresu klijenta prosljeđujemo u X-Real-IP. To omogućuje uzvodnom poslužitelju da donese odgovarajuće odluke ili pohrani zapise na temelju klijentovog izvornog IP-a. Zaglavlje X-Forwarded-For sadrži popis svih IP adresa koje pripadaju poslužiteljima kroz koje je klijent bio proxyiran prije nego što je stigao do ove točke. U gornjem isječku koda postavili smo ga na varijablu $proxy_add_x_forwarded_for. Ova će varijabla preuzeti vrijednost izvornog zaglavlja X-Forwarded-For uzetog od klijenta i dodati IP adresu Nginx proxy poslužitelja na kraj.
Ako želite da se direktive proxy_set_header referenciraju na više od jedne lokacije, možete ih premjestiti u kontekst server ili http. Razmotrite isječak konfiguracije u nastavku:
|
1 2 3 4 5 6 7 8 9 10 11 12 |
proxy_set_header HOST $host; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; location /match/here { proxy_pass http://example.com/new/prefix; } location /different/match { proxy_pass http://example.com; } |
Definiranje upstream konteksta za balansiranje opterećenja proksiranih veza
Do ovog trenutka razumijete kako napraviti jednostavan http proxy prema jednom pozadinskom upstream poslužitelju. Srećom, s Nginxom možete skalirati takvu konfiguraciju definiranjem grupa pozadinskih poslužitelja kojima se prosljeđuju zahtjevi na obradu.
Nginx pruža direktivu pod nazivom upstream koja se koristi za definiranje grupe poslužitelja. Unutar konfiguracije direktive morate navesti samo poslužitelje koji su sposobni obraditi klijentski zahtjev. Nginx kao proxy poslužitelj omogućuje skaliranje infrastrukture uz minimalan napor. Direktiva upstream mora biti navedena unutar http konteksta vaše Nginx konfiguracije.
Evo primjera koji prikazuje direktivu upstream:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
upstream several_backend_hosts { server host1.example.com; server host2.example.com; server host3.example.com; } server { listen 80; server_name example.com; location /proxy-me { proxy_pass http://several_backend_hosts; } } |
U gornjem isječku konfiguracijskog koda definirali smo upstream kontekst pod nazivom several_backend_hosts. Definirani naziv konteksta sada je dostupan unutar proxy prolaza. Može se koristiti kao da je riječ o običnoj domeni, kao što je prikazano u primjeru. Unutar bloka server, sve zahtjeve upućene na example.com/proxy-me/… prosljeđujemo u grupu koju smo definirali pomoću direktive upstream, u ovom slučaju, several_backend_hosts. Domaćin se odabire unutar grupe za obradu dolaznih zahtjeva primjenom konfigurabilnog algoritma. Prema zadanim postavkama, odabir slijedi round-robin (kružni) proces – svaki se zahtjev redom usmjerava na drugog domaćina.
Kako promijeniti upstream algoritam balansiranja
Kao što je gore istaknuto, proces odabira slijedi round-robin proces. U ovom odjeljku vidjet ćemo kako možemo izmijeniti algoritam balansiranja koji koristi upstream grupa. Da biste izmijenili algoritam, uključujete druge direktive ili zastavice unutar upstream konteksta kako je definirano u nastavku:
-
(round-robin) – ako nije navedena nijedna druga direktiva za balansiranje upstream-a, prema zadanim postavkama svakom poslužitelju definiranom u upstream kontekstu zahtjevi se prosljeđuju sekvencijalno, jedan za drugim.
-
least_conn – ova direktiva nalaže upstream-u da odabere pozadinski poslužitelj s najmanjim brojem aktivnih veza. To je primjenjivo u situacijama u kojima veze s jednim pozadinskim poslužiteljem mogu potrajati neko vrijeme.
-
hash – ova je direktiva uobičajena za memcached proksiranje. Veze se prosljeđuju pozadinskim poslužiteljima na temelju vrijednosti nasumično osiguranog hash ključa. Vrijednost hash ključa može biti varijabla, tekst ili kombinacija obojega. hash je ujedno i jedina metoda balansiranja koja zahtijeva unos od korisnika kako bi poslužio kao ključ koji će se koristiti za hash.
-
ip_hash – ova direktiva nalaže upstream-u da distribuira zahtjeve različitim poslužiteljima na temelju IP adrese klijenta. Prva tri okteta IP adrese ključ su za određivanje koji bi poslužitelj trebao obraditi zahtjev. Prednost ove direktive je što klijenti obično svaki put dobivaju isti poslužitelj, čime se osigurava dosljednost sesije.
Evo primjera kako možemo dodati direktivu algoritma balansiranja u upstream kontekst:
|
1 2 3 4 5 6 7 8 |
upstream several_backend_hosts { least_conn; server host1.example.com; server host2.example.com; server host3.example.com; } |
U gornjem isječku, Nginx će odabrati bilo koji od poslužitelja s najmanje veza za obradu dolaznog zahtjeva. Direktiva ip_hash slijedi istu sintaksu. Za direktivu hash morate navesti ključ po vlastitom izboru prema kojem će se vršiti hashiranje, evo primjera:
|
1 2 3 4 5 6 7 8 |
upstream several_backend_hosts { hash $remote_addr$remote_port consistent; server host1.example.com; server host2.example.com; server host3.example.com; } |
Hash koji se ovdje koristi bit će rezultat klijentove IP adrese i porta. Opcionalni parametar consistent implementira ketama algoritam konzistentnog hashiranja. To osigurava minimalan utjecaj na vašu predmemoriju ako promijenite svoje uzvodne poslužitelje.
Kako odrediti težinu poslužitelja za uravnoteženje
Prema zadanim postavkama, kada deklarirate pozadinske poslužitelje, svaki poslužitelj ima jednaku težinu. Pretpostavka je da svaki poslužitelj ima resurse i mogućnosti za rukovanje istom količinom opterećenja, naravno, to je uzimajući u obzir bilo koji algoritam uravnoteženja koji navedete u uzvodnom kontekstu. Da biste promijenili ovo zadano ponašanje, možete postaviti alternativnu težinu svakom poslužitelju tijekom deklaracije. Pogledajmo primjer:
|
1 2 3 4 5 |
upstream backend_hosts { server host1.example.com weight=2; server host2.example.com; server host3.example.com; } |
U ovom primjeru, host1.example.com primit će dvostruko više prometa od ostala dva poslužitelja. Težina za svaki poslužitelj prema zadanim je postavkama jedan.
Oslobađanje pozadinskih poslužitelja pomoću međuspremnika
Tijekom konfiguriranja proxyja u konfiguraciji vašeg poslužitelja, možda ćete biti zabrinuti zbog utjecaja dodavanja više poslužitelja u proces na performanse. Srećom, Nginx dolazi sa značajkama međuspremanja i predmemoriranja koje mogu pomoći u ublažavanju ovih problema s performansama.
Brzina dviju različitih veza sigurno će utjecati na klijentovo iskustvo prilikom usmjeravanja preko proxyja na drugi poslužitelj:
-
Prva veza je od klijenta do Nginx proxyja.
-
Druga veza je od Nginx proxyja do pozadinskog uzvodnog poslužitelja.
Nginx može prilagoditi svoje ponašanje kako bi po potrebi pomogao optimizirati bilo koju od veza.
Ako uklonimo međuspremnike, podaci s uzvodne pozadine počinju se odmah prenositi klijentu na Nginx proxyju. Ako znate da su vaši klijenti brzi, možete potpuno isključiti međuspremanje kako biste osigurali da podaci stignu do klijenta dovoljno brzo. Kada je međuspremanje uključeno, Nginx proxy privremeno pohranjuje podatke odgovora primljene od pozadinskog uzvodnog poslužitelja. Zatim šalje podatke klijentu ovisno o njegovoj brzini. Nakon što Nginx ima odgovor u svojim međuspremnicima, može zatvoriti vezu s pozadinskim poslužiteljem. Zatim će distribuirati podatke klijentu brzinom koju klijent podržava. Istovremeno, to omogućuje pozadinskom poslužitelju da nastavi obrađivati druge dolazne zahtjeve.
Prema zadanim postavkama, Nginx će imati uključeno međuspremanje. To je zato što ne možemo znati brzine veze klijenata. Klijenti obično imaju različite veze koje mogu biti sporije. U nastavku ćemo definirati različite direktive koje možemo navesti za prilagodbu ponašanja međuspremanja Nginxa. Direktive se mogu definirati u kontekstima http, server ili location, međutim, trebate imati na umu da se direktive za određivanje veličine konfiguriraju po zahtjevu. Stoga njihovo povećanje iznad onoga što je apsolutno nužno može utjecati na performanse vašeg poslužitelja kada ima previše dolaznih zahtjeva klijenata. Evo direktiva:
-
proxy_buffering – direktiva koja kontrolira je li međuspremanje aktivno za određeni kontekst i podređene kontekste. Zadana konfiguracija za proxy_buffering je „on”.
-
proxy_buffer_size – direktiva koja određuje veličinu međuspremnika za pohranu zaglavlja pronađenih u odgovoru s pozadinskog poslužitelja. Zaglavlja čine prvi dio odgovora s pozadinskog poslužitelja. Međuspremanje ovih zaglavlja odvojeno je od ostatka odgovora. Prema zadanim postavkama, postavljena veličina ovog međuspremnika ista je kao i za proxy_buffers. Međutim, ako su informacije u zaglavlju male, možete postaviti veličinu na nižu vrijednost.
-
proxy_buffers – direktiva koja kontrolira broj (prvi argument) i veličinu (drugi argument) međuspremnika za proksirane odgovore. Zadana konfiguracija specificira 8 međuspremnika veličine jednake jednoj memorijskoj stranici (bilo 4k ili 8k). Možete omogućiti međuspremanje više informacija povećanjem broja međuspremnika.
-
proxy_max_temp_file_size – direktiva koja određuje maksimalnu veličinu, po zahtjevu, za privremenu datoteku na disku. Privremene datoteke se stvaraju kada je uzvodni odgovor prevelik da bi stao u međuspremnik.
-
proxy_busy_buffers_size – direktiva koja određuje maksimalnu veličinu međuspremnika koji mogu proći kao „spremni za klijenta” i stoga zauzeti. Klijent može čitati podatke samo iz jednog međuspremnika odjednom. Međutim, međuspremnici su u redu čekanja za slanje klijentu u serijama. Možete odrediti veličinu prostora međuspremnika kojem je dopušteno biti u ovom stanju izmjenom ove direktive.
-
proxy_temp_file_write_size – direktiva koja određuje količinu podataka koju će Nginx odjednom zapisati u privremenu datoteku kada je odgovor s pozadinskog uzvodnog poslužitelja prevelik da bi stao u konfigurirane međuspremnike.
-
proxy_temp_path – direktiva koja određuje putanju do lokacije na disku gdje bi Nginx trebao pohraniti sve privremene datoteke kada je odgovor s uzvodnog pozadinskog poslužitelja prevelik da bi stao u konfigurirane međuspremnike.
Nginx je vrlo prilagodljiv, pružajući vam nekoliko direktiva za fino podešavanje ponašanja međuspremanja. U većini slučajeva zadane vrijednosti će raditi sasvim u redu. Istovremeno, dobro je znati da neke od ovih vrijednosti možete prilagoditi za svoju prilagođenu implementaciju. Najčešće ćete htjeti prilagoditi direktive proxy_buffers i proxy_buffer_size.
Ispod je primjer koji povećava broj dostupnih proxy međuspremnika za svaki uzvodni zahtjev. To čini dok istovremeno smanjuje veličinu međuspremnika koji pohranjuje zaglavlja:
|
1 2 3 4 5 6 7 8 9 10 11 12 |
server { proxy_buffering on; proxy_buffer_size 1k; proxy_buffers 24 4k; proxy_busy_buffers_size 8k; proxy_max_temp_file_size 2048m; proxy_temp_file_write_size 32k; location / { proxy_pass http://example.com; } } |
Pogledajmo kako možete brže isporučiti podatke brzim klijentima potpunim isključivanjem međuspremanja. Ako se dogodi da vaš klijent nije dovoljno brz, Nginx će automatski koristiti međuspremnike. Međutim, prvo će isprati podatke klijentu umjesto da čeka skupove međuspremnika. Ova konfiguracija dolazi s nedostatkom. Ova konfiguracija uzrokuje da veza s uzvodnim poslužiteljem ostane otvorena za spore klijente sve dok klijent ne primi sve podatke odgovora. Ako je međuspremanje postavljeno na „off”, koristit će se samo međuspremnik definiran direktivom proxy_buffer_size. Evo isječka koji pokazuje kako biste odredili isključivanje međuspremanja:
|
1 2 3 4 5 6 7 8 9 |
server { proxy_buffering off; proxy_buffer_size 4k; location / { proxy_pass http://example.com; } } |
-
Konfiguriranje visoko dostupne (HA) infrastrukture (neobavezno postavljanje)
Možete dodati redundantni skup load balancera u Nginx proxy konfiguraciju kako biste osigurali da je robusnija i stoga visoko dostupna. Konfiguracija visoke dostupnosti (HA) je infrastruktura bez jedne točke kvara. Load balanceri su dio ove konfiguracije. S više od jednog load balancera možete spriječiti potencijalno vrijeme zastoja ako jedan load balancer otkaže ili ode izvan mreže radi održavanja.
Kako implementirati Nginx proxy predmemoriranje za smanjenje vremena odziva
U prethodnom odjeljku raspravljali smo o tome kako koristiti međuspremnik (buffering) kako bismo oslobodili backend poslužitelje za obradu više zahtjeva. Nginx dolazi s još jednom značajkom koja nam omogućuje predmemoriranje podataka odgovora s backenda. To u potpunosti uklanja potrebu za povezivanjem s upstreamom za sve dolazne zahtjeve.
Implementacija proxy predmemorije
Direktiva proxy_cache_path omogućuje nam postavljanje predmemorije specificiranjem područja na disku koje će se koristiti za pohranu proxy sadržaja. Direktiva proxy_cache_path definira se u http kontekstu.
Sljedeći isječak konfiguracijskog koda primjer je kako možete implementirati sustav predmemoriranja:
|
1 2 3 4 5 6 |
http { proxy_cache_path /var/lib/nginx/cache levels=1:2 keys_zone=backendcache:8m max_size=50m; proxy_cache_key "$scheme$request_method$host$request_uri$is_args$args"; proxy_cache_valid 200 302 10m; proxy_cache_valid 404 1m; } |
U ovom isječku koda upotrijebili smo direktivu proxy_cache_path za definiranje direktorija u datotečnom sustavu koji će sadržavati našu predmemoriju. U ovom slučaju postavili smo direktorij /var/lib/nginx/cache. Slobodni ste definirati putanju direktorija po vlastitom izboru. Upotrijebite sljedeće naredbe za stvaranje odabranih direktorija, s ispravnim dozvolama i vlasništvom:
|
1 2 3 |
sudo mkdir -p /var/lib/nginx/cache sudo chown www-data /var/lib/nginx/cache sudo chmod 700 /var/lib/nginx/cache |
U isječku koda, parametar levels= određuje organizaciju predmemorije. Nginx će stvoriti ključ predmemorije sažimanjem (hashing) vrijednosti ključa (određenog pomoću direktive proxy_cache_key). Razine koje smo odredili (1:2) označavaju da će se stvoriti direktorij s jednim znakom (tj. posljednjim znakom sažete vrijednosti) s poddirektorijem od dva znaka (uzetim iz sljedeća dva znaka s kraja sažete vrijednosti). U većini slučajeva to vas neće brinuti. Međutim, dobro je znati kako to pomaže Nginxu u brzom pronalaženju relevantnih vrijednosti.
Parametar keys_zone= definira naziv zone predmemorije, u našem slučaju nazvali smo je backendcache. Ovdje također definiramo koliko metapodataka želimo pohraniti. U ovom primjeru pohranjujemo 8 MB ključeva. Nginx može pohraniti otprilike 8000 unosa za svaki megabajt. Parametar max_size određuje maksimalnu veličinu stvarnih predmemoriranih podataka, što je 50MB u našem primjeru.
Također biste trebali primijetiti korištenu direktivu proxy_cache_key. Ova direktiva određuje ključ koji ćemo koristiti za pohranu predmemoriranih vrijednosti. Koristit ćemo isti ključ za provjeru postoji li zahtjev unutar predmemorije. Odredili smo da taj ključ bude kombinacija sheme (http ili https), HTTP metode zahtjeva te traženog hosta i URI-ja.
Osim toga, upotrijebili smo direktivu proxy_cache_valid. Ova se direktiva može navesti više puta za različite statusne kodove. Omogućuje nam da odredimo koliko dugo se vrijednosti pohranjuju ovisno o statusnom kodu. U isječku koda odredili smo 10 minuta za kodove uspjeha i 1 minutu za 404 odgovore.
Budući da smo konfigurirali zonu predmemorije, sljedeći je korak primjena konfiguracije tako da kažemo Nginxu kada treba koristiti predmemoriju. Ispod je isječak konfiguracije koji prikazuje kako možemo implementirati korištenje ove predmemorije:
|
1 2 3 4 5 6 7 8 9 |
server { location /proxy-me { proxy_cache backendcache; proxy_cache_bypass $http_cache_control; add_header X-Proxy-Cache $upstream_cache_status; proxy_pass http://backend; } } |
U direktivi proxy_cache odredili smo da se za ovaj kontekst koristi zona predmemorije backendcache. Ako ste odabrali drugo ime u konfiguraciji predmemorije, ovdje ćete ga zamijeniti. Za svaki valjani unos, Nginx će provjeriti predmemoriju prije prosljeđivanja zahtjeva pozadinskom uzvodnom poslužitelju.
Definiramo direktivu proxy_cache_bypass za korištenje varijable $http_cache_control. Ova varijabla govori poslužitelju treba li odgovoriti predmemoriranim odgovorom ili svježom, nepredmemoriranom verzijom resursa. Ispravno postavljanje ove direktive omogućuje Nginxu da ispravno rukuje različitim vrstama dolaznih zahtjeva klijenata.
Također je navedeno dodatno zaglavlje pod nazivom X-Proxy-Cache. Ovo zaglavlje ima vrijednost varijable $upstream_cache_status. Ono nam daje informacije o tome je li zahtjev rezultirao pogotkom u predmemoriji, promašajem ili je predmemorija eksplicitno zaobiđena. Takve informacije mogu biti korisne za klijenta i ključne tijekom otklanjanja pogrešaka u aplikacijama.
Važne točke o predmemoriranju rezultata
Iako će predmemoriranje uvelike poboljšati performanse vašeg proxy poslužitelja, trebali biste uzeti u obzir sljedeće prilikom implementacije predmemoriranja:
Svi podaci povezani s osobnim podacima korisnika ne bi se trebali predmemorirati, kako bi se izbjegli scenariji u kojima su podaci jednog korisnika vidljivi drugom korisniku.
Vaši pozadinski poslužitelji trebali bi uzeti u obzir sve dinamičke elemente vaše web stranice. Imamo nekoliko Cache-Control zaglavlja koja možemo odrediti u našem odgovoru za različite svrhe. Raspravimo o njima:
-
no-cache – određuje da proxy mora provjeriti jesu li se podaci promijenili na pozadini prije posluživanja odgovora. Ovo je primjenjivo za dinamičke i važne podatke. ETag hashirano zaglavlje metapodataka provjerava se pri svakom zahtjevu i ako pozadina vrati istu hash vrijednost, poslužuje se prethodna vrijednost.
-
no-store – određuje da se primljeni podaci ne predmemoriraju, stoga će svaki zahtjev ići na poslužitelj po svježe podatke. Ovo je najsigurnije za osjetljive podatke.
-
private – određuje da nijedan zajednički prostor predmemorije ne smije predmemorirati podatke. Možete koristiti ovo zaglavlje za određivanje predmemoriranja u korisnikovom pregledniku, ali i za informiranje proxy poslužitelja da podatke smatra nevažećima za naknadne zahtjeve.
-
public – određuje javni odgovor i omogućuje predmemoriranje u bilo kojoj točki veze.
Možete odrediti koliko dugo želite da predmemorija traje u sekundama pomoću zaglavlja max-age. Različita gore definirana zaglavlja mogu vam pomoći u implementaciji predmemoriranja, dok istovremeno čuvaju osjetljive podatke sigurnima, dinamičke podatke svježima i, što je najvažnije, poboljšavaju performanse vašeg poslužitelja.
Ako vaši pozadinski poslužitelji pokreću Nginx poslužitelje, unutar blokova poslužitelja možete odrediti koliko dugo bi predmemorija trebala vrijediti. To možete učiniti dodavanjem direktive expires u konfiguraciju kao što je prikazano u nastavku:
|
1 2 3 4 5 6 7 |
location / { expires 59m; } location /check-me { expires -1; } |
Prvi blok omogućuje predmemoriranje sadržaja na 59 minuta, dok drugi blok označava da nema predmemoriranja. Ove se postavke primjenjuju na opcije zaglavlja Cache-Control, na primjer, „no-cache“ za drugi blok.
Možete koristiti direktivu add-header za postavljanje dodatnih vrijednosti:
|
1 2 3 4 |
location /private { expires -1; add_header Cache-Control "no-store"; } |
Zaključak
U ovom vodiču naučili smo o moćnim značajkama Nginxa. Nginx je i web poslužitelj i, što je najvažnije, reverzni proxy. Dizajn Nginxa omogućuje mu rukovanje tisućama istovremenih veza. To ga čini savršenim za uravnoteženje opterećenja. Zbog takvog dizajna, prosljeđivanje zahtjeva drugim pozadinskim poslužiteljima na obradu prilično je jednostavno.
Uz znanje iz ovog vodiča, trebali biste moći implementirati složene proxyje i load balancere, zahvaljujući fleksibilnosti Nginxa.
Evo nekoliko resursa koje možete pronaći na našem blogu koji vas mogu dodatno upoznati s Nginxom:
-
Kako instalirati LEMP stack (Linux, Nginx, MySQL PHP) na Ubuntu 20.04
-
Postavljanje Laravela, Nginxa i MySQL-a pomoću Docker Composea
Sretno s radom!
Komentari
Još nema komentara. Budite prvi.