Ponašanje i dostupnost direktiva prvenstveno ovise o učitanom MPM-u. MPM je kratica za MultiProcessing Module i oni određuju osnovni način na koji Apache rješava višeprocesnu obradu. Obradit ćemo tri cjeline:
- Opća optimizacija (General optimization)
- Optimizacija Event/Workera
- Optimizacija Preforka
Svaki se dio bavi time kako direktive utječu na performanse unutar pripadajućeg MPM-a i što treba uzeti u obzir pri optimizaciji Apachea u tom kontekstu.
1. Opća optimizacija
IfModule
Važna direktiva koju treba razumjeti pri radu s Apache poslužiteljima je IfModule uvjetni blok. Sastoji se od dva dijela: početnog bloka koji prihvaća naziv modula ili izvornu datoteku modula i završnog bloka. Kada je zadani modul učitan u Apache, sve direktive između početka i kraja IfModule bloka također se učitavaju u aktivnu konfiguraciju. Pogledajte primjer:
<ifModule mpm_prefork_module>
MaxSpareServers 16
</ifModule>
Timeout 60
U ovom primjeru MaxSpareServers se definira samo kada je učitan mpm_prefork_module. Timeout se primjenjuje uvijek jer se nalazi izvan IfModule bloka.
IfModule blokovi služe održavanju kompatibilnosti Apache konfiguracije prilikom promjene modula. Direktive su grupirane tako da se koriste samo kada je potreban modul doista učitan. Tako dobivate sintaktički ispravnu konfiguraciju čak i kada mijenjate module.
Ispravno omatanje direktiva unutar IfModule blokova smatra se najboljom praksom u Apache konfiguraciji i treba ga slijediti radi bolje kompatibilnosti.
Timeout
Ovo je broj sekundi koliko Apache čeka za uobičajene I/O događaje. Apache će odustati od zahtjeva koji se ne dovrše prije zadane Timeout vrijednosti.
Prava vrijednost ovisi i o prometnim navikama i o aplikacijama koje hostate. Idealno, Timeout treba biti što niži, ali i dalje dovoljno visok da velika većina redovnog prometa radi bez problema. Veliki timeoi, posebno iznad jedne minute, otvaraju prostor za SlowLoris stil DoS napada i produžuju čekanje korisnika u pregledniku kada nešto pođe po zlu. Niži timeout omogućuje Apacheu brži oporavak od zapetljanih veza. Treba pronaći ravnotežu.
Nemojte povećavati globalni Timeout radi jednog skripta ili korisnika kojem treba dulje vrijeme. Takvi problemi obično se rješavaju kroz .htaccess ili include datoteku za točno taj skript.
KeepAlive
Jednostavan on|off prekidač uključuje KeepAlive protokol za podržane preglednike. KeepAlive može donijeti i do 50% manje latencije te značajno poboljšati performanse Apachea. Funkcionira tako da preglednik ponovno koristi istu početnu vezu za naknadne zahtjeve koji se dogode unutar kratkog razdoblja.
KeepAlive je snažna funkcionalnost i u većini slučajeva treba biti uključena. Posebno dobro radi na modernim stranicama s mnogo elemenata jer smanjuje CPU i mrežni overhead.
Uz njega dolaze i dvije povezane direktive: MaxKeepAliveRequests i KeepAliveTimeout, koje imaju važnu ulogu u finom podešavanju.
MaxKeepAliveRequests
Ova direktiva postavlja ograničenje na broj zahtjeva koje pojedinačna KeepAlive veza smije obraditi. Kada se limit dosegne, Apache prisilno zatvara vezu i stvara novu za eventualne dodatne zahtjeve.
Idealna vrijednost ovisi o interpretaciji, ali općenito želite da bude barem jednaka najvećem broju elemenata na najposjećenijim stranicama poslužitelja.
Pravilo je da MaxKeepAliveRequests postavite na dvostruku vrijednost od najvećeg broja elemenata na tipičnim stranicama.
KeepAliveTimeout
Ova direktiva mjeri se u sekundama i definira koliko dugo veza ostaje neaktivna čekajući dodatne zahtjeve istog inicijatora. Budući da su takve veze dostupne samo tom inicijatoru, KeepAliveTimeout treba biti vrlo nizak. Niska vrijednost sprječava da previše KeepAlive veza blokira nove posjetitelje zbog prioriteta veze.
Veliki MaxKeepAliveRequests u kombinaciji s vrlo niskim KeepAliveTimeout dopušta aktivnim posjetiteljima ponovno korištenje veze, a istovremeno brzo oslobađa threadove od neaktivnih korisnika.
Preporuka konfiguracije: MaxKeepAliveRequests 500+ i KeepAliveTimeout 2. Najbolje radi na MPM Eventu.
2. Optimizacija Event/Workera
Ovaj dio opisuje direktive koje su važne kada radite s Worker baziranim MPM-ovima, uključujući i MPM Event i MPM Worker. To su višedretvena (multi-threaded) rješenja i neke se direktive drukčije ponašaju ovisno o učitanom MPM-u.
Kod Worker-based MPM-ova ServerLimit, ThreadsPerChild i MaxRequestWorkers snažno su povezani. Važno je razumjeti ulogu svake i kako promjena jedne utječe na ostale.
MPM Worker i MPM Event
MPM Event i MPM Worker u većini slučajeva rade gotovo identično. Razlika je vidljiva u načinu na koji rješavaju KeepAlive zahtjeve. MPM Worker zaključava threadove tijekom KeepAlive procesa, što izravno smanjuje broj threadova dostupnih za nove zahtjeve. MPM Event koristi poseban listener thread za svaki child proces. Taj listener obrađuje i redovne i KeepAlive zahtjeve pa zaključavanje threadova ne smanjuje kapacitet poslužitelja. Upravo zato je MPM Event bolji izbor, ali tek od Apachea 2.4 nadalje. Prije toga je bio nestabilan.
ServerLimit
ServerLimit predstavlja gornju granicu broja child procesa koje Apache smije imati. Praktična svrha mu je stvaranje tvrdog limita kojim se poslužitelj štiti od grešaka pri unosu MaxRequestWorkers vrijednosti. Time se sprječava stvaranje golemog broja procesa koje sustav ne može podnijeti, što može dovesti do prekida rada, gubitka prihoda, reputacije ili čak podataka.
ServerLimit je izravno povezan s thrashing pointom. To je maksimalan broj child procesa koje Apache može pokrenuti prije nego što potrošnja memorije sklizne u stalni swap. ServerLimit treba uskladiti s tim izračunom.
ThreadsPerChild
Ova direktiva definira koliko threadova svaki Apache child može upravljati. Svaki aktivni thread može obraditi jedan zahtjev. Zadana vrijednost 25 dobro radi u većini slučajeva i predstavlja solidan balans između child procesa i threadova.
Postoji i gornja granica koju kontrolira ThreadLimit, a ona je po zadanim postavkama 64. Ako želite više od 64 threada po childu, morate prilagoditi i ThreadLimit.
Povećanje ove vrijednosti omogućuje svakom childu obradu većeg broja zahtjeva uz manju potrošnju memorije i veći MaxRequestWorkers. Velika prednost većeg broja threadova unutar jednog childa jest dijeljeni pristup memorijskom cacheu. Threadovi jednog childa mogu dijeliti cache, dok threadovi između childova to ne mogu. Veći broj threadova po childu zato može donijeti bolju izvedbu. Glavni nedostatak dolazi prilikom recikliranja childa, kada se kapacitet poslužitelja privremeno smanjuje za broj threadova konfiguriranih u tom childu.
Snižavanje ThreadsPerChild radi suprotno. Tada vam treba više child procesa za isti MaxRequestWorkers, što povećava potrošnju memorije, ali smanjuje utjecaj recikliranja child procesa. Manje threadova znači i manje potencijalno zapetljanih threadova tijekom postupka recikliranja.
Pri postavljanju ThreadsPerChild uvijek razmišljajte o stvarnom poslužiteljskom okruženju i hardveru.
ThreadLimit
ThreadLimit postavlja maksimalnu vrijednost za ThreadsPerChild. To je tvrdi strop koji štiti od tipfelera i pogrešnih unosa. Na jačim poslužiteljima ponekad ga treba povećati kada je sustavu potrebno više od zadanih 64 threada po childu.
MaxRequestWorkers / MaxClients
Ova direktiva postavlja granicu aktivnih worker threadova kroz sve child procese i radi kao soft limit, dok ServerLimit preuzima ulogu tvrdog limita. Kada ukupan broj threadova dosegne ili prijeđe MaxRequestWorkers, Apache više ne pokreće nove child procese.
Određivanje MaxRequestWorkers ključno je za optimizaciju poslužitelja. Optimalna vrijednost ovisi o više promjenjivih faktora, što znači da konfiguraciju treba povremeno preispitivati na temelju prometa i korištenja resursa. Apache status Scoreboard izvrstan je alat za analizu performansi.
Na Worker-based MPM sustavima često radi izolirani third-party PHP handler poput mod_fcgid, PHP-FPM ili mod_lsapi. Takvi moduli izvršavaju PHP izvan Apachea i oslobađaju Apache za obradu lakših zahtjeva poput HTML-a, CSS-a, slika i sličnog. Zato Apache u tim konfiguracijama može podnijeti znatno veći broj zahtjeva, pa i više od 400 MaxRequestWorkers.
MinSpareThreads
Ovo je najmanji broj threadova koji trebaju ostati otvoreni i čekati nove zahtjeve. MinSpareThreads je višekratnik od ThreadsPerChild i ne može biti veći od MaxSpareThreads.
Preporuka je postaviti ga na 50% vrijednosti MaxRequestWorkers.
Spare threadovi su idle worker threadovi koji samo čekaju nove zahtjeve. Ako ih je manje od MinSpareThreads, Apache parent stvara novi child s još jednim paketom ThreadsPerChild threadova.
MaxSpareThreads
Ova direktiva određuje ukupan broj idle threadova dopuštenih na poslužitelju kroz sve child procese. Ako je idle threadova više od tog limita, parent će gasiti child procese kako bi smanjio potrošnju memorije tijekom slabijeg prometa.
Ograničenje broja idle threadova korisno je na manjim poslužiteljima s hardverskim ograničenjima, ali na modernijem hardveru često više nije toliko nužno.
Na snažnijim poslužiteljima s puno RAM-a i više CPU jezgri moguće je raditi tzv. open throttle konfiguraciju. Tada su svi dostupni threadovi stalno spremni. Memorijska potrošnja Apachea tada ostaje visoka, ali odziv je maksimalno brz jer se izbjegava overhead pokretanja novih procesa u naletima prometa. U takvoj konfiguraciji MinSpareThreads i MaxSpareThreads uskladite s MaxRequestWorkers.
StartServers
Ova direktiva definira početni broj child procesa koje Apache parent stvara kada se servis pokrene ili ponovno pokrene. Najčešće ostaje nepromijenjena jer Apache sam kontinuirano prati broj child procesa i threadova te prema MinSpareThreads odlučuje treba li kreirati nove child procese.
Ako je računate ručno, StartServers dobivate tako da MaxRequestWorkers podijelite s ThreadsPerChild i zaokružite prema dolje. Tako se svi child procesi stvore odmah pri pokretanju, bez čekanja, što je korisno na modernim poslužiteljima koji se povremeno ponovno pokreću radi promjene direktiva.
MaxConnectionsPerChild / MaxRequestsPerChild
Ova direktiva određuje koliko zahtjeva jedan Apache child može obraditi ukupno kroz sve threadove koje kontrolira. Nakon što dosegne limit, child se reciklira.
Služi kao zaštita od slučajnih curenja memorije (memory leak). Neki dijelovi koda koje threadovi izvršavaju mogu curiti memoriju i s vremenom je učiniti nedostupnom drugim procesima. Postavljanje limita za MaxConnectionsPerChild osigurava da Apache povremeno reciklira procese i smanji učinak takvih curenja.
Ako koristite vanjske handlere koda poput mod_fcgid, PHP-FPM ili mod_lsapi, često je potrebno postaviti MaxConnectionsPerChild na 0, dakle neograničeno, kako Apache ne bi prerano gasio threadove i uzrokovao povremene greške.
Ako sumnjate na curenje memorije, nemojte odmah postaviti nisku vrijednost. Krenite s 10.000 i spuštajte postupno.
3. Optimizacija Preforka
Ovaj dio pokriva direktive relevantne za MPM Prefork. Riječ je o nedretvenom (non-threaded) višeprocesnom modulu dizajniranom prvenstveno radi kompatibilnosti. Sastoji se od jednog Apache parent procesa koji upravlja svim child procesima. Za razliku od Worker-based MPM-ova, MPM Prefork optimizira se jednostavnije jer postoji 1:1 odnos Apache procesa i dolaznih zahtjeva. No loše skalira s prometom i što je promet veći, treba mu više hardvera.
MaxRequestWorkers / MaxClients
Ova direktiva kontrolira gornju granicu child procesa koje Apache parent smije držati u memoriji istovremeno. Budući da svaki child obrađuje jedan zahtjev, to je ujedno i maksimalan broj simultanih zahtjeva koje poslužitelj može podnijeti.
Ako je postavljena prenisko, Apache ne koristi sav raspoloživ hardver, što znači sporije učitavanje stranica i bačeni novac. Ako je previsoka, Apache može preopteretiti sustav i završiti u thrashing scenariju, s mogućim rušenjem poslužitelja i gubitkom podataka.
MinSpareServers
Ova direktiva definira minimalan broj idle child procesa koje Apache parent treba držati spremnima. Idle child je već preforkan Apache proces koji čeka novi zahtjev. To je bitno za brz odziv poslužitelja. Ako broj idle childova padne ispod zadane vrijednosti, Apache stvara novi child brzinom od jednog u sekundi dok ne zadovolji uvjet.
Nikada ovu vrijednost nemojte postaviti na nulu. Dobro je pravilo postaviti je na 25% MaxRequestWorkers vrijednosti.
MaxSpareServers
MaxSpareServers kontrolira maksimalan broj idle Apache child procesa koji smiju istovremeno raditi. Ako ih ima više, Apache gasi višak.
Ako je MaxSpareServers manji od MinSpareServers, Apache će ga automatski povećati na MinSpareServers + 1.
Dobro pravilo je postaviti ga na dvostruku vrijednost MinSpareServers.
Na poslužiteljima s puno RAM-a i više CPU jezgri moguće je koristiti open throttle pristup, gdje su svi child procesi stalno spremni. To povećava memorijsku potrošnju, ali daje najbolje moguće vrijeme odziva. U tom slučaju MinSpareServers i MaxSpareServers postavite jednako kao MaxRequestWorkers.
StartServers
StartServers definira koliko će Apache child procesa biti kreirano pri pokretanju. Rijetko se mijenja jer Apache inače sam odlučuje koliko child procesa treba.
Na modernim poslužiteljima koji periodično ponovno pokreću Apache radi novih konfiguracija ili rotacije logova, svaka sekunda prekida rada je važna. Tada ima smisla StartServers postaviti jednako MinSpareServers vrijednosti kako bi pokretanje bilo brže.
ServerLimit
ServerLimit je gornja granica za MaxRequestWorkers i uglavnom služi kao zaštitni strop protiv pogrešnog unosa.
Treba ga prilagoditi ako poslužitelj mora podnijeti više od zadanih 256 simultanih zahtjeva.
I ovdje se veže uz thrashing point. ServerLimit treba uskladiti s maksimalnim brojem child procesa koje hardver može podnijeti prije nego memorija sklizne u stalni swap.
Povećavanje ServerLimit nije preporučljivo s MPM Preforkom jer više od 256 simultanih zahtjeva u ovom modelu traži vrlo ozbiljan hardver.
MaxConnectionsPerChild / MaxRequestsPerChild
Ova direktiva predstavlja broj zahtjeva koje jedan Apache child može obraditi.
I ovdje služi kao zaštita od curenja memorije. Kod koji Apache izvršava ponekad ima greške koje uzrokuju curenje memorije. S vremenom takva curenja smanjuju količinu iskoristive memorije child procesa. Recikliranje child procesa rješava taj problem.
Dobro pravilo je ne postavljati ovu vrijednost prenisko. Ako se pojave problemi s curenjem memorije, krenite s 10.000 i spuštajte postupno.
Povezana područja
Savjetodavna područja vezana uz ovu temu
Ova su područja rada usklađena s temom članka i daju čišći prijelaz od edukativnog sadržaja do konkretne implementacije.
Nastavite čitati
Povezani članci
Prvo po zajedničkim kategorijama, a zatim po najjačem preklapanju u tagovima.