mod_fcgid
Par PlaceOweb le jeudi, mai 6 2010, 19:32 - PHP - Lien permanent
Afin de mutualiser l'hébergement PHP, et pour pallier aux failles de sécurité, le mod fcgi reste une très bonne alternative (d'ailleurs utilisé par les hébergeurs).
Introduction
PHP en couplage avec un serveur Web, les différents moyens de communication, leurs avantages et inconvénients :
Si vous cherchez la performance, rien ne remplace encore aujourd'hui un module de serveur Web : fusionner PHP dans le serveur Web est le meilleur moyen d'obtenir des performances élevées car il n'y a aucune communication inter-processus à gérer par le noyau, tout est encapsulé dans un seul processus, celui du serveur Web.
En revanche cette solution demeure très difficile à sécuriser si l'on veut héberger plusieurs sites sur une même instance de serveur. Ce n'est pas le cas de tout le monde, si vous n'avez pas de problématique de partage de PHP entre plusieurs sites Web différents, utilisez clairement la SAPI module.
Le module de serveur donne les meilleures performances, après entre FastCGI+SuEXEC et FPM, c'est à peu près équivalent même si FPM semble légèrement l'emporter. CGI reste lui, tout en bas du classement avec les performances les moins bonnes.
Fast CGI
- FastCGI est une technique permettant la communication entre un serveur HTTP et un logiciel indépendant.
Par exemple sur Apache 2.x on peut utiliser le module mod_fcgid.
Et utiliser sa documentation : Apache Module mod_fcgid
PS : Notez qu'il s'agit de la documentation Apache HTTP Server Version 2.3, et que le nom des attributs des variables du mod FastCGI a changé !
Erreurs rencontrés
Internal Server Error
The server encountered an internal error or misconfiguration and was unable to complete your request.
Please contact the server administrator, webmaster@placeoweb.com and inform them of the time the error occurred, and anything you might have done that may have caused the error.
More information about this error may be available in the server error log.
Internal Server Error The server encountered an internal error or misconfiguration and was unable to complete your request. Please contact the server administrator, webmaster@placeoweb.com and inform them of the time the error occurred, and anything you might have done that may have caused the error. More information about this error may be available in the server error log.Voir le l'ancien beug : Bug #41593 FastCGI does not handle graceful reload/shutdown
Petit programme de test, pour éviter les erreurs
<?php $timetosleep = isset($_REQUEST['time'])?$_REQUEST['time']:30; $a = time(); sleep($timetosleep); echo time()-$a; echo "Done with $timetosleep"; ?>
Configuration brutale qui semble stable :
<VirtualHost *:80> <IfModule mod_fcgid.c> SuexecUserGroup userweb1 users PHP_Fix_Pathinfo_Enable 1 <Directory /var/www/userweb1 /> Options +ExecCGI AllowOverride All AddHandler fcgid-script .php FCGIWrapper /var/www/php-fcgi-scripts/userweb1 /php-fcgi-starter .php Order allow,deny Allow from all </Directory> # http://httpd.apache.org/mod_fcgid/mod/mod_fcgid.html # IdleScanInterval FcgidIdleScanInterval Default: FcgidIdleScanInterval 120 IdleScanInterval 600 # IdleTimeout FcgidIdleTimeout Default: FcgidIdleTimeout 300 IdleTimeout 600 # IPCCommTimeout FcgidIOTimeout Default: FcgidIOTimeout 40 IPCCommTimeout 600 # IPCConnectTimeout FcgidConnectTimeout Default: FcgidConnectTimeout 3 IPCConnectTimeout 300 </IfModule> </VirtualHost>
Ressources
- Apache Module mod_fcgid
- Tutoriel : Comment installer APACHE2 avec mod_fcgi et PHP5 sur Ubuntu 9.04
- How To Set Up Apache2 With mod_fcgid And PHP5 On Ubuntu 8.10
- Bug #41593 FastCGI does not handle graceful reload/shutdown
- PHP-FPM - A simple and robust FastCGI Process Manager for PHP
- Apache with fcgid: acceptable performance and better resource utilization
- Possibility to use also php4 along default php5 with mod_fcgid and suexec
- Using PHP with mod_fcgid
# Communication timeout: Default value is 20 seconds IPCCommTimeout 60 # Connection timeout: Default value is 3 seconds #IPCConnectTimeout 3
# Number of PHP childs that will be launched. Leave undefined to let PHP decide. #DefaultInitEnv PHP_FCGI_CHILDREN 3 # Maximum requests before a process is stopped and a new one is launched #DefaultInitEnv PHP_FCGI_MAX_REQUESTS 5000
PHP_FCGI_CHILDREN
- php.net PHP_FCGI_CHILDREN
- Apache, PHP Fastcgi and PHP_FCGI_CHILDREN
- optimal settings for max-procs, PHP_FCGI_CHILDREN
PHP terminera un processus fils lorsque le nombre de requêtes spécifié par PHP_FCGI_MAX_REQUESTS a été atteint.
La variable d'environnement PHP_FCGI_CHILDREN contrôle le nombre de fils que PHP appelle pour gérer les demandes. La variable d'environnement PHP_FCGI_MAX_REQUESTS détermine la durée de vie, en nombre de requêtes, de chaque fils.
SAPI : FastCGI Process Manager
# Short-Description: starts php5-fpm # Description: starts the PHP FastCGI Process Manager daemon
SERVEUR_WEB_PHP:~# /etc/init.d/php5-fpm restart Gracefully shutting down php5-fpm warning, no pid file found - php5-fpm is not running ? Starting php5-fpm Jul 29 10:05:14.336182 [ALERT] [pool www] pm.min_spare_servers(0) must be a positive value Jul 29 10:05:14.336373 [ERROR] failed to post process the configuration
Solution sur dotdeb
There should be a default for pm.min_spare_servers / pm.max_spare_servers (5 and 35 is used in comments in the default ini). This default can be provided in the default ini (just uncomment the lines), or hardcoded in php-fpm itself. Otherwise, the ini won’t work out of the box, resulting in errors like: This prevents: [ALERT] [pool www] pm.min_spare_servers(0) must be a positive value [ERROR] failed to post process the configuration
SERVEUR_WEB_PHP:/etc/php5/fpm# /etc/init.d/php5-fpm restart Gracefully shutting down php5-fpm warning, no pid file found - php5-fpm is not running ? Starting php5-fpm Jul 29 10:13:41.791364 [WARNING] [pool www] pm.start_servers is not set. It's been set to 20. ................................... failed
SERVEUR_WEB_PHP:/etc/php5/fpm# ps faux root 2725 0.0 0.2 174828 5252 ? Ss 10:13 0:00 /usr/bin/php5-fpm --fpm-config /etc/php5/fpm/php5-fpm.conf www-data 2726 0.0 0.2 174824 4628 ? S 10:13 0:00 \_ /usr/bin/php5-fpm --fpm-config /etc/php5/fpm/php5-fpm.conf www-data 2727 0.0 0.2 174824 4628 ? S 10:13 0:00 \_ /usr/bin/php5-fpm --fpm-config /etc/php5/fpm/php5-fpm.conf www-data 2728 0.0 0.2 174824 4628 ? S 10:13 0:00 \_ /usr/bin/php5-fpm --fpm-config /etc/php5/fpm/php5-fpm.conf www-data 2729 0.0 0.2 174824 4628 ? S 10:13 0:00 \_ /usr/bin/php5-fpm --fpm-config /etc/php5/fpm/php5-fpm.conf
PHP 5.2.13, 5.2.14 et PHP 5.3.2, 5.3.3 README.FastCGI (php-5.3.3\sapi\cgi\README.FastCGI) : SAPI : CGI / FastCGI
There are a few tuning parameters that can be tweaked to control the performance of FastCGI PHP. The following are environment variables that can be set before running the PHP binary: PHP_FCGI_CHILDREN (default value: 0) This controls how many child processes the PHP process spawns. When the fastcgi starts, it creates a number of child processes which handle one page request at a time. Value 0 means that PHP willnot start additional processes and main process will handle FastCGI requests by itself. Note that this process may die (because of PHP_FCGI_MAX_REQUESTS) and it willnot respawned automatic. Values 1 and above force PHP start additioanl processes those will handle requests. The main process will restart children in case of their death. So by default, you will be able to handle 1 concurrent PHP page requests. Further requests will be queued. Increasing this number will allow for better concurrency, especially if you have pages that take a significant time to create, or supply a lot of data (e.g. downloading huge files via PHP). On the other hand, having more processes running will use more RAM, and letting too many PHP pages be generated concurrently will mean that each request will be slow. PHP_FCGI_MAX_REQUESTS (default value: 500) This controls how many requests each child process will handle before exitting. When one process exits, another will be created. This tuning is necessary because several PHP functions are known to have memory leaks. If the PHP processes were left around forever, they would be become very inefficient.
PHP 4.x README.FastCGI
There are a few tuning parameters that can be tweaked to control the performance of FastCGI PHP. The following are environment variables that can be set before running the PHP binary: PHP_FCGI_CHILDREN (default value: 8) This controls how many child processes the PHP process spawns. When the fastcgi starts, it creates a number of child processes which handle one page request at a time. So by default, you will be able to handle 8 concurrent PHP page requests. Further requests will be queued. Increasing this number will allow for better concurrency, especially if you have pages that take a significant time to create, or supply a lot of data (e.g. downloading huge files via PHP). On the other hand, having more processes running will use more RAM, and letting too many PHP pages be generated concurrently will mean that each request will be slow. PHP_FCGI_MAX_REQUESTS (default value: 500) This controls how many requests each child process will handle before exitting. When one process exits, another will be created. This tuning is necessary because several PHP functions are known to have memory leaks. If the PHP processes were left around forever, they would be become very inefficient.
Les sources de la version PHP 5.3.2 : cgi_main.c
if (fastcgi) { /* How many times to run PHP scripts before dying */ if (getenv("PHP_FCGI_MAX_REQUESTS")) { max_requests = atoi(getenv("PHP_FCGI_MAX_REQUESTS")); if (max_requests < 0) { fprintf(stderr, "PHP_FCGI_MAX_REQUESTS is not valid\n"); return FAILURE; } } /* make php call us to get _ENV vars */ php_php_import_environment_variables = php_import_environment_variables; php_import_environment_variables = cgi_php_import_environment_variables; /* library is already initialized, now init our request */ fcgi_init_request(&request, fcgi_fd); #ifndef PHP_WIN32 /* Pre-fork, if required */ if (getenv("PHP_FCGI_CHILDREN")) { char * children_str = getenv("PHP_FCGI_CHILDREN"); children = atoi(children_str); if (children < 0) { fprintf(stderr, "PHP_FCGI_CHILDREN is not valid\n"); return FAILURE; } fcgi_set_mgmt_var("FCGI_MAX_CONNS", sizeof("FCGI_MAX_CONNS")-1, children_str, strlen(children_str)); /* This is the number of concurrent requests, equals FCGI_MAX_CONNS */ fcgi_set_mgmt_var("FCGI_MAX_REQS", sizeof("FCGI_MAX_REQS")-1, children_str, strlen(children_str)); } else { fcgi_set_mgmt_var("FCGI_MAX_CONNS", sizeof("FCGI_MAX_CONNS")-1, "1", sizeof("1")-1); fcgi_set_mgmt_var("FCGI_MAX_REQS", sizeof("FCGI_MAX_REQS")-1, "1", sizeof("1")-1); }
- If you are using a dynamic application environment, make sure that PHP_FCGI_CHILDREN is always set to 0; that way, PHP will never try to manage worker threads.
- If you are using a static environment, decide where you're going to control it and make it clear in the comments in your httpd.conf so you remember six months later!
- Don't make too many PHP threads; usually your machine will die of CPU overload if you try to do too much work in the threads; allow httpd to buffer the network requests. More worker threads and CPU threads in your machine is usually counter-productive.
Software caused connection abort: mod_fcgid: ap_pass_brigade failed in handle_request function
- Debian Bug report logs 537922 apache2: mod_fcgid trouble since update
- FCGID ap_pass_brigade error
- fcgid error with file uploads or email forwards
FastCGI Process Manager (FPM) SAPI
FPM (FastCGI Process Manager) is an alternative PHP FastCGI implementation with some additional features (mostly) useful for heavy-loaded sites.
Configuration de FPM : FPM utilise la syntaxe php.ini pour son propre fichier de configuration - php-fpm.conf.
- PHP 5.3.3 inclus : FastCGI Process Manager (FPM) SAPI, voir le ChangeLog et Request for Comments: FPM SAPI inclusion
- PHP 5.3.3 Added FastCGI Process Manager (FPM) SAPI. (Tony)
- PHP 5.3.2 Fixed bug #50168 (FastCGI fails with wrong error on HEAD request to non-existant file). (Dmitry)
- PHP 5.3.1 Fixed bug #27051 (Impersonation with FastCGI does not exec process as impersonated user). (Pierre)
- PHP 5.3.0
- Added ".htaccess" style user-defined php.ini files support for CGI/FastCGI.
- Improved and cleaned CGI code:
- FastCGI is now always enabled and cannot be disabled. See sapi/cgi/CHANGES for more details. (Dmitry)
- Added CGI SAPI -T option which can be used to measure execution time of script repeated several times. (Dmitry)
- Fixed bug #45786 (FastCGI process exited unexpectedly). (Dmitry)
- PHP 5.2.2 Fixed bug #40286 (PHP fastcgi with PHP_FCGI_CHILDREN don't kill children when parent is killed). (Dmitry)
- PHP 5.2.0 Improved FastCGI SAPI: (Dmitry)
- Removed source compatibility with libfcgi.
- Optimized access to FastCGI environment variables by using HashTable instead of linear search.
- Allowed PHP_FCGI_MAX_REQUESTS=0 that assumes no limit.
- Allowed PHP_FCGI_CHILDREN=0 that assumes no worker children. (FastCGI requests are handled by main process itself)
- Les RPM de Remi - Forums » User support » FastCGI Process Manager (FPM) SAPI
SERVEUR_WEB_PHP:~# apt-cache search php- | grep binary php5-cgi - server-side, HTML-embedded scripting language (CGI binary) php5-fpm - server-side, HTML-embedded scripting language (FPM binary) SERVEUR_WEB_PHP:~# dpkg -l | grep php ii libapache2-mod-php5 5.3.3-0.dotdeb.0 server-side, HTML-embedded scripting language (Apache 2 module ii php5 5.3.3-0.dotdeb.0 server-side, HTML-embedded scripting language (metapackage) ii php5-cgi 5.3.3-0.dotdeb.0 server-side, HTML-embedded scripting language (CGI binary) ii php5-cli 5.3.3-0.dotdeb.0 command-line interpreter for the php5 scripting language ii php5-common 5.3.3-0.dotdeb.0 Common files for packages built from the php5 source
Environement
SERVEUR_WEB_PHP:/var/www# apache2ctl -version Server version: Apache/2.2.9 (Debian) Server built: Nov 14 2009 21:07:23 SERVEUR_WEB_PHP:/var/www# php -version PHP 5.3.2-0.dotdeb.1 with Suhosin-Patch (cli) (built: Mar 9 2010 11:42:01) Copyright (c) 1997-2009 The PHP Group Zend Engine v2.3.0, Copyright (c) 1998-2010 Zend Technologies SERVEUR_WEB_PHP:/var/www# dpkg -l | grep cgi ii libapache2-mod-fcgid 1:2.2-1 an alternative module compat with mod_fastcg ii php5-cgi 5.3.2-0.dotdeb.1 server-side, HTML-embedded scripting languag SERVEUR_WEB_PHP:/var/www# dpkg -l | grep php ii libapache2-mod-php5 5.3.2-0.dotdeb.1 server-side, HTML-embedded scripting languag ii php5 5.3.1-0.dotdeb.1 server-side, HTML-embedded scripting languag ii php5-cgi 5.3.2-0.dotdeb.1 server-side, HTML-embedded scripting languag ii php5-cli 5.3.2-0.dotdeb.1 command-line interpreter for the php5 script ii php5-common 5.3.2-0.dotdeb.1 Common files for packages built from the php ii php5-curl 5.3.2-0.dotdeb.1 CURL module for php5 ii php5-gd 5.3.2-0.dotdeb.1 GD module for php5 ii php5-ldap 5.3.2-0.dotdeb.1 LDAP module for php5 ii php5-mcrypt 5.3.2-0.dotdeb.1 MCrypt module for php5 ii php5-mysql 5.3.2-0.dotdeb.1 MySQL module for php5 ii php5-suhosin 5.3.2-0.dotdeb.1 suhosin module for php5 ii php5-xmlrpc 5.3.2-0.dotdeb.1 XML-RPC module for php5 ii php5-xsl 5.3.2-0.dotdeb.1 XSL module for php5 SERVEUR_WEB_PHP:/var/www# dpkg -l | grep apache ii apache2 2.2.9-10+lenny6 Apache HTTP Server metapackage ii apache2-mpm-prefork 2.2.9-10+lenny6 Apache HTTP Server - traditional non-threade ii apache2-suexec 2.2.9-10+lenny6 Standard suexec program for Apache 2 mod_sue ii apache2-utils 2.2.9-10+lenny6 utility programs for webservers ii apache2.2-common 2.2.9-10+lenny6 Apache HTTP Server common files ii libapache2-mod-fcgid 1:2.2-1 an alternative module compat with mod_fastcg ii libapache2-mod-php5 5.3.2-0.dotdeb.1 server-side, HTML-embedded scripting languag SERVEUR_WEB_PHP:/var/log/apache2# vim /var/www/php-fcgi-scripts/userweb1/php-fcgi-starter #!/bin/sh PHPRC=/etc/php5/cgi/ export PHPRC export PHP_FCGI_MAX_REQUESTS=5000 export PHP_FCGI_CHILDREN=8 exec /usr/lib/cgi-bin/php
http://mon.site.web/phpinfo.php Environment Variable Value PHPRC /etc/php5/cgi/ PHP_FCGI_CHILDREN 8 PATH /usr/local/bin:/usr/bin:/bin PWD /var/www/php-fcgi-scripts/userweb1 SHLVL 0 PHP_FCGI_MAX_REQUESTS 5000
Configuration du mod_fcgi
- IdleScanInterval FcgidIdleScanInterval
- IdleTimeout FcgidIdleTimeout
- IPCCommTimeout FcgidIOTimeout
- IPCConnectTimeout FcgidConnectTimeout
FcgidIdleScanInterval (anciennement IdleScanInterval)
- FcgidIdleScanInterval Directive
- Description: scan interval for idle timeout process
- Syntax: FcgidIdleScanInterval seconds
- Default: FcgidIdleScanInterval 120
- Context: server config
- Status: External
- Module: mod_fcgid
This is the interval at which the module will search for processes which have exceeded FcgidIdleTimeout or FcgidProcessLifeTime.
FcgidIdleTimeout (anciennement IdleTimeout)
- FcgidIdleTimeout Directive
- Description: An idle FastCGI application will be killed after FcgidIdleTimeout
- Syntax: FcgidIdleTimeout seconds
- Default: FcgidIdleTimeout 300
- Context: server config, virtual host
- Status: External
- Module: mod_fcgid
Application processes which have not handled a request for this period of time will be terminated, if the number of processses for the class exceeds FcgidMinProcessesPerClass. A value of 0 disables the check.
This idle timeout check is performed at the frequency of the configured FcgidIdleScanInterval.
This setting will apply to all applications spawned for this server or virtual host. Use FcgidCmdOptions to apply this setting to a single application.
FcgidIOTimeout (anciennement IPCCommTimeout)
- FcgidIOTimeout Directive
- Description: Communication timeout to FastCGI server
- Syntax: FcgidIOTimeout seconds
- Default: FcgidIOTimeout 40
- Context: server config, virtual host
- Status: External
- Module: mod_fcgid
This is the maximum period of time the module will wait while trying to read from or write to a FastCGI application. Note
The FastCGI application must begin generating the response within this period of time. Increase this directive as necessary to handle applications which take a relatively long period of time to respond.
This setting will apply to all applications spawned for this server or virtual host. Use FcgidCmdOptions to apply this setting to a single application.
FcgidConnectTimeout (anciennement IPCConnectTimeout)
- FcgidConnectTimeout Directive
- Description: Connect timeout to FastCGI server
- Syntax: FcgidConnectTimeout seconds
- Default: FcgidConnectTimeout 3
- Context: server config, virtual host
- Status: External
- Module: mod_fcgid
This is the maximum period of time the module will wait while trying to connect to a FastCGI application on Windows. (This directive is not respected on Unix, where AF_UNIX defaults will apply.)
This setting will apply to all applications spawned for this server or virtual host. Use FcgidCmdOptions to apply this setting to a single application.
php_value FCGI
<virtualHost *:80> php_value register_globals on </VirtualHost>
# /etc/init.d/apache2 restart Restarting web server: apache2We failed to correctly shutdown apache, so we're now killing all running apache processes. This is almost certainly suboptimal, so please make sure your system is working as you'd expect now! (warning). ... waiting .Syntax error on line 24 of /etc/apache2/sites-enabled/mysite: Invalid command 'php_value', perhaps misspelled or defined by a module not included in the server configuration failed!
Solution
# vim "/var/www/php-fcgi-scripts/mysite/php-fcgi-starter"
#!/bin/sh PHPRC=/etc/php5/cgi/ export PHPRC export PHP_FCGI_MAX_REQUESTS=5000 export PHP_FCGI_CHILDREN=8 exec /usr/lib/cgi-bin/php -d register_globals="1"
Ressources
Changing php_value for one vhost in fcgi...
What's in /var/www/php-cgi-scripts/web4/php-cgi-starter?
et ajout de directive PHP dans le le php-cgi-starter
My experience with Apache 2.2, fcgi...
For example enable register_globals on (apache2) / .htaccess : php_value register_globals 1 Only if you are running php as a apache module, that do not work in suexec.
Why php_value directives for php.ini set in .htaccess fail when php is running as cgi or fcgi
Those are Apache directives, but in CGI mode Apache calls the php binary, which turn reads php.ini. Since the binary doesn’t read httpd.conf it has no effect on PHP. As PHP isn’t loaded into Apache, Apache doesn’t know what to do with the directives and borks.