Apache en php tuning door Piethein Strengholt (2009)

Inmiddels draai ik weer wat jaren mee en wil ik wat kennis en ervaring delen op het gebied van Performance tuning voor Webservers onder Linux. Hier een aantal goede tips.

Allereerst is het belangrijk om te weten met processing module apache is gecompileerd. Hier kom je snel achter door het volgende commando uit te voeren:

[root@ns1 linux]# httpd -l
Compiled in modules:
core.c
prefork.c
http_core.c
mod_so.c
[root@ns1 linux]#

In het bovenstaande voorbeeld is te zien dat apache is gecompileerd om gebruik te maken van de prefork module. De worker module. Hierover is genoeg informatie te vinden op het internet en de werkwijze is ongeveer hetzelfde om die reden beperk ik mij tot de prefork module. De processing module bepaalt hoe apache schaalt en het omgaat met grote hoeveelheden verzoeken. Door het aanmaken van nieuwe en meerdere processen is apache in staat meer verzoeken af te handelen. Hierbij is het belangrijk een balans te vinden tussen niet te veel processen en ook niet te weinig. Indien er te weinig processen worden aangemaakt is apache niet in staat alle drukte af te handelen. Worden er te veel processen aangemaakt dan bestaat de kans dat de server door de hoeveelheid geheugen heenloopt of dat het systeem alleen maar bezig is met het beheren van de processen.

Als we zoeken in de httpd.conf onder de sectie prefork.c zien we een aantal regels staan. Een aantal belangrijke om te weten:

StartServers, MinSpareServers, MaxSpareServers

De StartServers vertelt met hoeveel processen apacge minimaal moet worden opgestart.
De MinSpareServers vertelt hoeveel processen er minimaal actief moeten blijven.
De MaxSpareServers vertelt hoeveel processen er maximaal aangemaakt mogen worden.

Belangrijk om te weten is dat er altijd een verschil moet zijn tussen de Min en Max. Indien deze aan elkaar gelijk zijn zal de Max met een aantal van 1 worden verhoogd.

Een andere belangrijke regel is de MaxRequestsPerChild. Deze waarde bepaalt na hoeveel verzoeken het proces moet worden afgesloten. Indien deze waarde gelijk is aan 0 blijven de processen altijd leven. Ik raad ten sterkste af deze waarde gelijk te zetten aan, omdat tijdens rustigere tijden de processen afgesloten moeten worden. Een goede waarde is tussen de 1000 en 10000.

De MaxClients waarde is een belangrijke waarde die bepaalt hoeveel connecties er tegelijkertijd actief mogen zijn. Indien dit aantal overschreven wordt gaat de server verzoeken in de wachtbak plaatsen (queue). De default waarde is 256 is zou voldoende moeten zijn voor normale servers. Voor zwaardere machines kan deze waarde verhoogd worden. Voor de prefork is doorgaans de ServerLimit dezelfde waarde als de MaxClients. Zet daarom de ServerLimit niet te hoog.

De ThreadsPerChild bepaalt hoeveel threads de server per proces mag aanmaken. Deze is default 25.

Andere belangrijke waarden zijn de Timeout. Deze bepaalt na hoeveel seconde de server een timeout moet geven. Ik adviseer deze waarde niet te hoog te zetten.

Timeout 60

Verder zijn de KeepAlive, MaxKeepAliveRequests, KeepAliveTimeout

De KeepAlive bepaalt of dezelfde gebruiker meerdere connecties per seconde mag aanmaken. Het maximaal aantal connecties wordt bepaald door de MaxKeepAliveRequests waarde. De KeepAliveTimeout waarde bepaalt hoe lang er gewacht moet worden voor de volgende connectie van dezelfde gebruiker. Mijn advies is om de KeepAlive aan te zetten maar de overige waardes niet te hoog.

KeepAlive On
MaxKeepAliveRequests 40
KeepAliveTimeout 5

Hebben we behalve apache ook php draaien dan is het belangrijk om hier ook het een en ander te bekijken. De configuratie van php is onder de /etc/php.ini te vinden. De memory_limit is de belangrijkste waarde die bepaalt hoeveel geheugen het php script binnen het apache proces in beslag mag nemen. Pas op met deze waarde! Ik heb situaties gezien waarbij slecht geprogrammeerde scripts de gehele server neer haalde. Mijn advies is rond de 32M behalve indien er goede redenen zijn om deze te verhogen. Pas verder ook op met de max_execution_time en max_input_time. Als deze op zeer hoge aantallen staan kan de server ook onderuit gaan.

max_execution_time = 15 ; Maximum execution time of each script, in seconds
max_input_time = 30 ; Maximum amount of time each script may spend parsing request data
memory_limit = 30M