Re: Debian Sarge, Apache2, Suexec2, mod_fastcgi, php5-fcgi HowTo
Posted: 2005-03-23 11:55
Ok, ich habe das jetzt alles ein bisschen getestet (zuerst in der Produktion installieren und dann in der Testumgebung testen... :P ). Und muss mich gleich mal korrigieren: wenn PHP_FCGI_CHILDREN gesetzt ist, wird die Anzahl der Child-Prozesse immer auf diesem Wert gehalten, mehr dazu weiter unten.
Also, was man verstehen sollte ist, dass es zwei (eigentlich drei) Modi gibt, das FastCGI-Modul laufen zu lassen und zwei Modi für den PHP-FastCGI-Client.
FastCGI-Modul
(http://www.fastcgi.com/mod_fastcgi/docs ... stcgi.html):
1) Statischer Modus
Dieser Modus wird mit der FastCgiServer-Direktive eingeschalten. Es werden dann genau -processes (default 1) Clientprozesse gestartet. Stirbt ein Clientprozess wird er wieder neu angeworfen.
2) Dynamischer Modus
Dieser Modus wird mit SetHandler/Action eingeschalten und mit FastCgiConfig konfiguriert. Es werden bei Bedarf neue Prozesse gestartet und wenn kein Bedarf mehr besteht, werden sie wieder gekillt (mit SIGTERM).
3) Externer Server
z.B um Zope anzusprechen
Interessant finde ich, dass im Howto die Hauptseite im statischen Modus konfiguriert wird und die VHosts im dynamischen Modus. Ich kann bestätigen, dass es ohne FastCgiServer-Direktive, dafür mit ScriptAlias auf der Hauptseite genauso funktioniert.
PHP-Client
1) PHP_FCGI_CHILDREN=0 oder unset
PHP verhält sich wie man es von einem FastCGI-Client erwarten würde: 1 Prozess, der Anfragen entgegennimmt, abarbeitet und zurückliefert.
2) PHP_FCGI_CHILDREN>0
PHP startet PHP_FCGI_CHILDREN Prozesse,die alle Anfragen entgegennehmen und abarbeiten. Stirbt einer dieser Prozesse (spätestens nach PHP_FCGI_MAX_REQUESTS Anfragen), wird er aufs neue gestartet.
Interessant ist, wie das Spawnen neuer Prozesse im dynamischen Modus von FastCGI funktioniert (zumindest in meinen Tests): Jedes mal, wenn eine Anfrage länger braucht als in -startDelay angegeben, wird ein neuer Prozess gestartet (ausser es gibt schon -maxClassProcesses oder -maxProcesses). Und zwar egal, ob es noch genug andere freie Prozesse gibt! Das hat zwei Konsequenzen:
- startDelay sollte auf jeden Fall größer sein, als ein typischer Seitenaufruf braucht.
- wenn auf einmal große Last daherkommt, spawnt FastCGI sehr schnell die maximale Anzahl an Prozessen
Der zweite Punkt ist imho kein Nachteil, denn das Maximum an Prozessen sollte so gewählt sein, dass es die Maschine noch aushält. In meinem Belastungstest habe ich damit auch einen Bombendurchsatz erhalten. Man sollte auch bedenken, dass PHP_FCGI_CHILDREN mal mehr Prozesse gestartet werden, als FastCGI glaubt, und es ist wahrscheinlich anzuraten, die Killingpolicy aggressiver zu machen.
Meine Config, mit der ich bis jetzt ganz zufrieden bin:
PHP_FCGI_CHILDREN=4
FastCgiConfig -idle-timeout 300 -killInterval 60 -maxClassProcesses 5 -maxProcesses 400 -minProcesses 0 -multiThreshold 80 -startDelay 5
Allerdings habe ich das nur rudimentär getestet und die Skripts verwenden keine DB-Zugriffe. 1600 offene DB-Connections sind wahrscheinlich ein bisschen viel. :)
Also, was man verstehen sollte ist, dass es zwei (eigentlich drei) Modi gibt, das FastCGI-Modul laufen zu lassen und zwei Modi für den PHP-FastCGI-Client.
FastCGI-Modul
(http://www.fastcgi.com/mod_fastcgi/docs ... stcgi.html):
1) Statischer Modus
Dieser Modus wird mit der FastCgiServer-Direktive eingeschalten. Es werden dann genau -processes (default 1) Clientprozesse gestartet. Stirbt ein Clientprozess wird er wieder neu angeworfen.
2) Dynamischer Modus
Dieser Modus wird mit SetHandler/Action eingeschalten und mit FastCgiConfig konfiguriert. Es werden bei Bedarf neue Prozesse gestartet und wenn kein Bedarf mehr besteht, werden sie wieder gekillt (mit SIGTERM).
3) Externer Server
z.B um Zope anzusprechen
Interessant finde ich, dass im Howto die Hauptseite im statischen Modus konfiguriert wird und die VHosts im dynamischen Modus. Ich kann bestätigen, dass es ohne FastCgiServer-Direktive, dafür mit ScriptAlias auf der Hauptseite genauso funktioniert.
PHP-Client
1) PHP_FCGI_CHILDREN=0 oder unset
PHP verhält sich wie man es von einem FastCGI-Client erwarten würde: 1 Prozess, der Anfragen entgegennimmt, abarbeitet und zurückliefert.
2) PHP_FCGI_CHILDREN>0
PHP startet PHP_FCGI_CHILDREN Prozesse,die alle Anfragen entgegennehmen und abarbeiten. Stirbt einer dieser Prozesse (spätestens nach PHP_FCGI_MAX_REQUESTS Anfragen), wird er aufs neue gestartet.
Interessant ist, wie das Spawnen neuer Prozesse im dynamischen Modus von FastCGI funktioniert (zumindest in meinen Tests): Jedes mal, wenn eine Anfrage länger braucht als in -startDelay angegeben, wird ein neuer Prozess gestartet (ausser es gibt schon -maxClassProcesses oder -maxProcesses). Und zwar egal, ob es noch genug andere freie Prozesse gibt! Das hat zwei Konsequenzen:
- startDelay sollte auf jeden Fall größer sein, als ein typischer Seitenaufruf braucht.
- wenn auf einmal große Last daherkommt, spawnt FastCGI sehr schnell die maximale Anzahl an Prozessen
Der zweite Punkt ist imho kein Nachteil, denn das Maximum an Prozessen sollte so gewählt sein, dass es die Maschine noch aushält. In meinem Belastungstest habe ich damit auch einen Bombendurchsatz erhalten. Man sollte auch bedenken, dass PHP_FCGI_CHILDREN mal mehr Prozesse gestartet werden, als FastCGI glaubt, und es ist wahrscheinlich anzuraten, die Killingpolicy aggressiver zu machen.
Meine Config, mit der ich bis jetzt ganz zufrieden bin:
PHP_FCGI_CHILDREN=4
FastCgiConfig -idle-timeout 300 -killInterval 60 -maxClassProcesses 5 -maxProcesses 400 -minProcesses 0 -multiThreshold 80 -startDelay 5
Allerdings habe ich das nur rudimentär getestet und die Skripts verwenden keine DB-Zugriffe. 1600 offene DB-Connections sind wahrscheinlich ein bisschen viel. :)