„Nginx” prieš „Apache”: serverio programinės įrangos palyginimas

Amžina dilema: kas gi geresnis?

Jei dirbi su web serveriais, tikrai ne kartą esi girdėjęs šį amžiną ginčą – Nginx ar Apache? Tai tarsi klausimai „iPhone ar Android” ar „Vim ar Emacs” – žmonės turi savo nuomonę ir ja labai tiki. Bet skirtingai nuo fanatiškų diskusijų, čia tikrai yra objektyvių skirtumų, kurie gali lemti tavo projekto sėkmę ar nesėkmę.

Apache egzistuoja nuo 1995-ųjų ir ilgą laiką buvo absoliutus lyderis. Nginx atsirado 2004-aisiais kaip atsakas į tai, kas vadinama „C10K problema” – kaip efektyviai apdoroti 10,000 vienu metu vykstančių prisijungimų. Šiandien abi technologijos yra brandžios, patikimos ir naudojamos milijonuose serverių visame pasaulyje.

Bet kurį pasirinkti? Atsakymas, kaip ir dažnai IT pasaulyje – priklauso. Priklauso nuo tavo projekto specifikos, komandos žinių, infrastruktūros ir daugelio kitų dalykų. Pabandykime išsiaiškinti.

Architektūros skirtumai: kodėl tai svarbu praktikoje

Apache naudoja procesų arba thread’ų modelį. Paprasčiau tariant, kiekvienam prisijungimui (arba jų grupei) sukuriamas atskiras procesas ar thread’as. Tai reiškia, kad jei turi 1000 aktyvių vartotojų, serveris turi valdyti 1000 procesų ar thread’ų. Skamba logiškai, bet problema ta, kad kiekvienas procesas/thread’as naudoja atmintį ir sistemos resursus.

Nginx veikia visiškai kitaip – jis naudoja asinchroninį, įvykiais grįstą (event-driven) modelį. Vienas Nginx darbo procesas gali apdoroti tūkstančius prisijungimų vienu metu. Tai veikia panašiai kaip Node.js – neblokuojantis I/O, event loop ir visa kita. Praktiškai tai reiškia, kad Nginx gali aptarnauti daug daugiau vienu metu prisijungusių vartotojų naudodamas mažiau RAM ir CPU.

Realybėje tai atrodo taip: jei turi svetainę su 10,000 vienu metu prisijungusių lankytojų, Apache gali suėsti kelis gigabaitus RAM, o Nginx išsiverss su keliais šimtais megabaitų. Esu matęs serverius, kur po migracijos iš Apache į Nginx RAM naudojimas nukrito nuo 8GB iki 2GB, o serveris dirbo net greičiau.

Konfigūracijos filosofija ir .htaccess drama

Apache turi vieną labai patogią funkciją – .htaccess failus. Tai leidžia konfigūruoti serverį katalogų lygmenyje, be root prieigos. Puiku shared hosting aplinkai ar kai nori greitai pakeisti URL rewrite taisykles nekeisdamas pagrindinės konfigūracijos. Bet čia slypi ir problema.

Kiekvieną kartą, kai Apache apdoroja užklausą, jis turi patikrinti ar nėra .htaccess failų visame kelyje nuo root iki tikslo failo. Tai reiškia papildomus disk I/O operacijas KIEKVIENAI užklausai. Jei tavo svetainė gauna 1000 užklausų per sekundę, tai tampa rimtu bottleneck’u.

Nginx neturi .htaccess palaikymo. Viskas konfigūruojama centralizuotai per pagrindinius config failus. Iš pradžių tai atrodo kaip trūkumas, bet praktikoje tai skatina geresnę konfigūracijos valdymo praktiką. Naudoji version control, automatizuotą deployment’ą ir žinai tiksliai, kas kur sukonfigūruota.

Štai tipinis Apache .htaccess pavyzdys:

„`
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php/$1 [L]
„`

O tas pats Nginx konfigūracijoje:

„`
location / {
try_files $uri $uri/ /index.php?$query_string;
}
„`

Nginx sintaksė gali atrodyti keistoka iš pradžių, bet ji daug aiškesnė ir efektyvesnė. Nereikia mokytis sudėtingų regex taisyklių su RewriteCond ir RewriteRule – dažniausiai pakanka try_files direktyvos.

Statinio turinio tiekimas ir reverse proxy galimybės

Čia Nginx tikrai šviečia. Jis buvo sukurtas būtent tam – greitai ir efektyviai tiekti statinį turinį. Jei tavo svetainė turi daug nuotraukų, CSS, JavaScript failų, Nginx juos atiduos žymiai greičiau nei Apache. Benchmarkuose Nginx paprastai 2-3 kartus greitesnis statinio turinio tiekime.

Bet dar įdomesnė Nginx stiprybė – reverse proxy funkcionalumas. Jis puikiai tinka kaip frontend serveris, kuris priima visus užklausimus ir toliau juos persiunčia backend serveriams. Štai tipinė setup’o schema, kurią naudoju daugelyje projektų:

Nginx frontend’e klauso 80/443 portų, tiekia statinį turinį tiesiogiai, o dinaminius užklausimus persiunčia į backend – tai gali būti Apache su PHP, Node.js aplikacija, Python Django ar bet kas kita. Tokia architektūra leidžia maksimaliai išnaudoti abiejų serverių privalumus.

Praktinis pavyzdys – e-commerce svetainė su dideliu produktų katalogu. Visos produktų nuotraukos, CSS, JS failai tiekiami per Nginx. O kai vartotojas prideda produktą į krepšelį ar vykdo pirkimą, užklausa eina į Apache + PHP backend’ą. Rezultatas – greita svetainė ir efektyvus resursų panaudojimas.

Modulių sistema ir funkcionalumo išplėtimas

Apache turi milžinišką modulių ekosistemą. Nori HTTP/2? Yra modulis. Reikia WebDAV? Yra modulis. Autentifikacija per LDAP? Žinoma, yra modulis. Apache moduliai kompiliuojami kaip DSO (Dynamic Shared Objects) ir gali būti įkeliami/iškeliami runtime metu be serverio perkompiliavimo.

Populiariausi Apache moduliai:
– mod_rewrite – URL perrašymui
– mod_security – web application firewall
– mod_ssl – SSL/TLS palaikymui
– mod_proxy – proxy funkcionalumui
– mod_php – PHP integracijai

Nginx modulių sistema istoriškai buvo statinė – norėjai naują modulį, reikėjo perkompiliuoti visą Nginx. Bet nuo 1.9.11 versijos atsirado dynamic modules palaikymas. Vis tiek Nginx modulių ekosistema mažesnė nei Apache, bet pagrindiniai dalykai yra.

Įdomu tai, kad daugelis Nginx modulių yra įkompiluoti į core ir tiesiog įjungiami konfigūracijoje. Pavyzdžiui, gzip kompresija, SSL, proxy – visa tai out of the box. Su Apache dažnai reikia įsitikinti, kad reikiami moduliai įjungti.

Jei planuoji naudoti egzotiškesnį funkcionalumą ar trečiųjų šalių integraciją, Apache turbūt turės daugiau pasirinkimų. Bet 90% projektų Nginx standartinio funkcionalumo pilnai pakanka.

PHP ir aplikacijų integracijos niuansai

Čia labai svarbi tema, nes dauguma web projektų vis dar naudoja PHP. Apache turi mod_php – PHP interpreteris veikia tiesiogiai Apache procese. Tai patogu ir paprasta setup’inti, bet ne efektyviausias variantas.

Problema su mod_php ta, kad PHP interpreteris užkraunamas kiekvienam Apache procesui, net jei tas procesas tiekia tik statinį turinį. Tai reiškia, kad jei Apache procesas atiduoda CSS failą, jis vis tiek turi užkrautą visą PHP interpretatorių atmintyje. Švaistymas.

Nginx negali naudoti mod_php, nes jo architektūra tai neleidžia. Vietoj to naudojamas PHP-FPM (FastCGI Process Manager). Tai atskiras PHP procesų pool’as, su kuriuo Nginx komunikuoja per FastCGI protokolą. Iš pradžių tai atrodo kaip papildomas komplikavimas, bet praktikoje tai geresnis sprendimas:

– PHP procesai atskirti nuo web serverio
– Galima nepriklausomai scale’inti PHP ir web server
– Geresnė resursų kontrolė ir izoliacijos
– Galima naudoti skirtingas PHP versijas skirtingiems projektams

Apache irgi gali naudoti PHP-FPM (per mod_proxy_fcgi), ir tai actually rekomenduojamas būdas modernėse setup’uose. Bet istoriškai Apache + mod_php buvo default’as, ir daug kas vis dar taip naudoja.

Praktinis patarimas: nesvarbu ar naudoji Apache ar Nginx, setup’ink PHP-FPM. Tai modernus, efektyvus ir lankstus būdas. Vienintelis minusas – šiek tiek sudėtingesnė pradinė konfigūracija, bet atsipirks.

Load balancing ir high availability scenarijai

Jei tavo projektas auga ir vieno serverio nebepakanka, reikia load balancing’o. Nginx čia turi aiškų pranašumą – load balancing funkcionalumas yra core dalyje ir labai paprastas naudoti.

Paprasčiausias Nginx load balancer config:

„`
upstream backend {
server backend1.example.com;
server backend2.example.com;
server backend3.example.com;
}

server {
location / {
proxy_pass http://backend;
}
}
„`

Ir viskas – turite round-robin load balancing’ą tarp trijų serverių. Nginx palaiko įvairius load balancing algoritmus: round-robin, least connections, IP hash, generic hash. Plus health checks – jei backend serveris neatsako, Nginx automatiškai nukreips traffic’ą į kitus.

Apache irgi gali daryti load balancing per mod_proxy_balancer, bet tai nėra jo stiprioji pusė. Konfigūracija sudėtingesnė, funkcionalumas ribotas. Praktikoje, jei reikia load balancing’o, dažniausiai naudojamas Nginx kaip frontend load balancer, o backend’e gali būti Apache ar bet kas kita.

Real-world scenario: turiu projektą su 5 backend serveriais. Nginx frontend’e daro SSL termination, load balancing, caching ir statinio turinio tiekimą. Backend serveriuose sukasi Apache + PHP-FPM aplikacijos. Tokia architektūra leidžia lengvai pridėti ar pašalinti backend serverius, daryti rolling updates be downtime.

Dar vienas Nginx privalumas – session persistence (sticky sessions). Jei tavo aplikacija naudoja PHP sessions failuose (ne Redis ar memcached), reikia užtikrinti, kad tas pats vartotojas visada patektų į tą patį backend serverį. Nginx tai daro lengvai su ip_hash arba sticky moduliu.

Saugumo aspektai ir best practices

Abi platformos yra brandžios ir saugios, bet yra niuansų. Apache turi ilgesnę istoriją, vadinasi ir daugiau istorinių security issues. Bet tai nereiškia, kad jis nesaugus – tiesiog reikia sekti updates ir taikyti patches.

Nginx turi mažesnį attack surface dėl paprastesnės architektūros. Mažiau kodo – mažiau potencialių bugų. Plus, Nginx procesas paprastai veikia su non-privileged user teisėmis, o master procesas su root tik startup metu.

Svarbūs saugumo patarimai abiem platformoms:

**Išjunk nereikalingus modulius.** Apache default’e įjungia daug modulių, kurių greičiausiai nereikia. Kiekvienas įjungtas modulis – potenciali security rizika. Peržiūrėk ir išjunk visa, ko nenaudoji.

**Paslėpk server version.** Default’e ir Apache, ir Nginx response header’iuose rodo savo versiją. Tai duoda potencialiems atakuotojams informacijos. Apache: `ServerTokens Prod`, Nginx: `server_tokens off;`

**Naudok ModSecurity ar panašų WAF.** ModSecurity puikiai veikia su Apache ir yra Nginx versija. Tai web application firewall, kuris gali blokuoti įprastas atakas – SQL injection, XSS ir pan.

**Rate limiting.** Apsaugok nuo brute force ir DDoS atakų. Nginx turi puikų rate limiting modulį built-in. Apache reikia mod_evasive ar mod_qos.

**SSL/TLS konfigūracija.** Naudok tik modernius protokolus (TLS 1.2+), stiprius cipher suites. Mozilla turi puikų SSL config generator’ių abiem platformoms.

Praktikoje esu matęs daugiau prastai sukonfigūruotų Apache serverių nei Nginx, bet tai greičiausiai todėl, kad Apache populiaresnis shared hosting’uose, kur saugumo standartai žemesni. Teisingai sukonfigūruotos abi platformos yra saugios.

Kas gi laimi šiame mūšyje?

Atėjome į tą vietą, kur turėčiau pasakyti aiškų nugalėtoją, bet… jo nėra. Ir tai gerai, nes reiškia, kad turime pasirinkimą pagal savo poreikius.

Rinkis Nginx jei:
– Tau svarbus performance ir efektyvus resursų naudojimas
– Planuoji high-traffic projektą su tūkstančiais concurrent connections
– Reikia reverse proxy ar load balancing funkcionalumo
– Nori modernios, aiškios konfigūracijos
– Dirbi su microservices architektūra

Rinkis Apache jei:
– Reikia shared hosting aplinkos su .htaccess palaikymu
– Naudoji daug specifinių, egzotiškų modulių
– Komanda jau turi gilią Apache patirtį
– Projektas nedidelis ir performance nėra kritinis
– Reikia maksimalios compatibility su legacy sistemomis

O geriausias variantas? Naudok abu. Nginx kaip frontend – reverse proxy, load balancer, statinio turinio serveris. Apache backend’e su PHP-FPM ar kitomis aplikacijomis. Taip gauni geriausius abiejų pasaulių dalykus.

Pats šiuo metu daugumoje naujų projektų naudoju Nginx. Jis paprastesnis, greitesnis ir geriau tinka moderniai web architektūrai. Bet turiu ir Apache serverių, kurie veikia metų metus be problemų. Svarbiausia ne technologija, o kaip ją naudoji.

Ir dar vienas dalykas – nebijok eksperimentuoti. Setup’ink testinę aplinką, palyginki performance, pažiūrėk kaip jaučiasi su tavo specifiniu workload. Benchmarkai internete rodo vidurkius, bet tavo projektas nėra vidutinis. Gali būti, kad tau Apache veiks geriau, nors visi sako, kad Nginx greitesnis. Arba atvirkščiai.

Technologijų pasaulis nuolat keičiasi. Gal už kelių metų diskutuosime apie Caddy ar kažką visiškai naujo. Bet Apache ir Nginx tikrai išliks dar ilgai – per daug kritinės infrastruktūros ant jų pastatyta. Taigi mokykis, eksperimentuok ir rinkis tai, kas veikia tau.

Parašykite komentarą

El. pašto adresas nebus skelbiamas. Būtini laukeliai pažymėti *