El módulo de PHP de Apache funciona muy bien como configuración por defecto y es muy fácil de instalar. Pero tiene algunos inconvenientes:
- El módulo de PHP de Apache tiene que cargarse en cada petición, por lo tanto el uso de memoria RAM es más alto
- El módulo Prefork utiliza más CPU y RAM que Worker
Así que, seremos capaces de atender más peticiones con menos recursos. Aunque puede que tengamos problemas con algunos módulos o configuraciones como APC, o el número de conexiones mysql abiertas (se incrementará porque el número de peticiones concurrentes será por hilo), aunque notaremos la diferencia.
Lo primero, como digo en todas las páginas de esta serie de tutoriales, es que todo esto está probado con Ubuntu Server 12.04, así que puede que algunas cosas varíen en otros sabores de Linux, aunque lo importante es siempre igual. Puede que me veas utilizar apt-get para instalar paquetes y sudo para ejecutar cosas como root, eso deberás adaptarlo a tu distribución. También el nombre de los paquetes puede que cambie, aunque seguro que son parecidos
Contents
Instalación
Tenemos que instalar el MPM Worker, el módulo Fcgid y php-cgi, así que:
$ sudo apt-get install apache2-mpm-worker libapache2-mod-fcgis php5-cgi php-apc
Si tenemos la instalación de PHP hecha como módulo de Apache, nos dirá que debe eliminar libapache2-mod-php5 o apache-mpm-prefork.
Activar FCGId y configurar PHP
El siguiente paso es activar mod_fcgid:
$ sudo a2enmod fcgid
Tras ello, debemos crear un script de envolvente (wrapper script) donde colocaremos la configuración básica para lanzar los procesos CGI. El archivo lo podemos colocar en /usr/bin, /usr/local/bin o incluso dentro de nuestro document root (aunque no te lo recomiendo, pero lo podemos colocar en un nivel o directorio anterior). En el ejemplo, el archivo lo colocaré en /usr/local/bin/php-wrapper y tiene este contenido:
PHP_FCGI_MAX_REQUESTS=10000
export PHP_FCGI_MAX_REQUESTS
PHP_FCGI_CHILDREN=5
export PHP_FCGI_CHILDREN
exec /usr/lib/cgi-bin/php5-cgi -d apc.shm_size=50M
La última parte: «-d apc.shm_size=50M» es para utilizar un caché de opcodes por usuario de 50Mb. Lo podemos cambiar para ajustar nuestra configuración dependiendo de la memoria de nuestro servidor o del uso que hagamos de APC.
También definimos PHP_FCGI_MAX_REQUESTS que es el número de peticiones antes de que se reinicien los procesos hijo (cada hijo podrá atender a varios clientes), pero es buena idea reiniciar de vez en cuando los procesos para limpiar fugas de memoria (memory leaks), que pueden ser causadas por fallos en PHP o por algunos scripts mal costruidos (eso nos pasa a todos).
PHP_FCGI_CHILDREN es el número de hijos que esta instancia va a lanzar. Depende de los recursos de nuestro sistema, podemos incrementar este número dependiendo de la CPU y RAM que tengamos disponible y a medida que aumentemos el número podremos atender a más clientes a la vez.
/usr/bin/php-fcgi es nuestro ejecutable de php actuando como cgi, puede que lo tengas en esa ruta o puede que no, si es así, búscalo con locate o find.
Ahora, debemos decirle a Apache que use esta configuración. Para ello, en los archivos de configuración de nuestro VirtualHost (en el ejemplo era /etc/apache2/sites-available/totaki.com, debemos insertar los siguientes cambios (en negrita):
<VirtualHost *:80> ServerAdmin info@totaki.com ServerName totaki.com ServerAlias www.totaki.com DocumentRoot /home/cloud/www/totaki.com/www <Ifmodule mod_fcgid.c> # See /etc/apache2/mods-available/fcgid.conf for (fcgid-script) AddHandler fcgid-script .php .php5 .phtml FcgidWrapper /usr/local/bin/php-wrapper .php FcgidWrapper /usr/local/bin/php-wrapper .php5 FcgidWrapper /usr/local/bin/php-wrapper .phtml </IfModule> <Directory /> Options FollowSymLinks AllowOverride All</Directory> <Directory /home/cloud/www/totaki.com/www/> Options FollowSymLinks MultiViews +ExecCGI AllowOverride All Order allow,deny allow from all</Directory> ErrorLog "/home/cloud/www/totaki.com/logs/error.log" LogLevel warn CustomLog "/home/cloud/www/totaki.com/logs/access.log" combined</VirtualHost>
Ahora, sólo nos queda reiniciar el servidor. Crearemos un script sencillo para verificar que estamos funcionando com PHP-CGI, y accederemos a la dirección donde colocamos el script:
Un php.ini personalizado para cada Virtualhost
Con esta configuración no podemos utilizar php_value en .htaccess para modificar la configuración de php para un directorio en especial. Pero podemos configurar un archivo php.ini diferente para cada virtualhost defniendo la directiva PHPRC en la configuración de nuestro VirtualHost dentro de nuestro script envolvente de PHP. En este ejemplo, ésta es la configuración que he utilizado para el VirtualHost:
<VirtualHost *:80> ServerAdmin info@totaki.com ServerName totaki.com ServerAlias www.totaki.com DocumentRoot /home/cloud/www/totaki.com/www <Ifmodule mod_fcgid.c> # See /etc/apache2/mods-available/fcgid.conf for (fcgid-script) AddHandler fcgid-script .php .php5 .phtml FcgidInitialEnv PHPRC "/home/cloud/www/totaki.com/php/" FcgidWrapper /usr/local/bin/php-wrapper .php FcgidWrapper /usr/local/bin/php-wrapper .php5 FcgidWrapper /usr/local/bin/php-wrapper .phtml </IfModule> <Directory /> Options FollowSymLinks AllowOverride All </Directory> <Directory /home/cloud/www/totaki.com/www/> Options FollowSymLinks MultiViews +ExecCGI AllowOverride All Order allow,deny allow from all </Directory> ErrorLog "/home/cloud/www/totaki.com/logs/error.log" LogLevel warn CustomLog "/home/cloud/www/totaki.com/logs/access.log" combined </VirtualHost>
Ahora, colocamos un fichero php.ini en /home/cloud/www/totaki.com/www. Recuerda que cada VirtualHost puede tener una configuración PHPRC diferente, siempre que tengan un ServerName diferente.
Configuración CGI a nivel de sistema
Se recomienda tener parte de la configuración fuera de la configuración del VirtualHost. Podemos ver todos los parámetros que podemos tocar de Fcgid aquí, pero pondré algo más abajo los que uso más frecuentemente. Algunos de estos parámetros pueden ser también definidos dentro del VirtualHost. De todas formas, voy a crear /etc/apache2/conf.d/cgisettings.conf:
<IfModule mod_fcgid.c> FcgidBusyScanInterval 10 FcgidMaxProcesses 20 FcgidMaxRequestLen 1073741824 </IfModule>
Aquí vemos:
- FcgidBusyScanInterval: es el intervalo en el que el proceso buscará hijos ocupados.
- FcgidMaxProccesses: es el número total de procesos CGI a lanzar
- FcgidMaxRequestLen: es el tamaño total de la petición. Es útil si en tu aplicación soportas subida de ficheros. Antiguamente, por defecto, aquí había un valor alto, pero ahora no, por lo que tendremos que aumentarlo a meno.
Podemos además definir la directiva FcgidMaxProcessesPerClass que define el número máximo de procesos que puede lanzar cada VirtualHost.
Advertencia con Shellshock bug
Hace un tiempo saltó la alerta del bug ShellShock, puede ser letal para nosotros y es muy fácilmente explotable si utilizamos esta configuración en nuestro servidor. Por tanto, asegúrate de terner instalada la última versión de bash.
Deja un comentario