Clicky

Apache mod_fcgid + PHP-FPM en CentOS para múltiples usuarios

Apache PHP-FPM

Las ventajas que aporta la técnica FPM son aún más evidentes en estructuras online como los CMS

Mejorar la velocidad de carga de los sitios web es de suma importancia en la era de los dispositivos móviles. Hoy en día, muchas aplicaciones online se realizan mediante sistemas de gestión de contenidos (CMS) como el que yo utilizo en mis sitios que es Joomla!. Sin embargo, los CMS utilizan una gran cantidad de librerías (datos fuente utilizados por el código), de forma que una sola página puede emplear miles y miles de elementos que deben ser cargados e interpretados por los navegadores de Internet.

¿Que es el módulo fcgid de Apache?

mod_fcgid es una alternativa de alto rendimiento para mod_cgi o mod_cgid, que inicia un suficiente número de instancias del programa CGI para manejar solicitudes simultáneas, y que estos programas sigan funcionando para manejar más solicitudes entrantes. Se ve favorecido por los desarrolladores de PHP, por ejemplo, como una alternativa preferida a la ejecución de mod_php en proceso, y ofrece un rendimiento muy similar.

La mayoría de los sitios que sirven gran número de páginas utilizan Apache con mod_php. Aunque esto es a menudo la opción más fácil y rápida, puede que en algunos casos no sea la situación ideal. En este artículo se explica fcgid, una forma de ejecutar PHP que no sea mod_php y cómo conseguir configurarlo para varios sitios de un mismo servidor web trabajando al unísono con PHP-FPM.

¿Qué es PHP-FPM?

FPM (FastCGI Process Manager - Manejador de Procesos FastCGI) es una implementación alternativa al PHP FastCGI con algunas características adicionales (la mayoría) útiles para sitios web con mucho tráfico.

Una petición PHP, uno de los lenguajes informáticos más extendidos en internet, consiste en la interpretación de archivos o scripts asociados, recurriendo a elementos y acciones que deben ejecutarse. Por defecto, un archivo PHP se lee de la misma manera y de forma independiente en cada petición, sin tener en cuenta si ya se ha enviado una petición anterior.

Con PHP-FPM, los elementos e instrucciones invocados en una petición se conservan en la memoria, es decir, se guardan en la caché del servidor, para así poder reutilizarlos directamente si vuelve a enviarse esa misma petición.

De esta forma, el servidor de archivos recibe menos peticiones, lo que implica una reducción de la carga en la máquina («load average») y una mejor disponibilidad de los recursos para realizar otras tareas.

Las ventajas que aporta la técnica FPM son aún más evidentes en estructuras online como los CMS, que se basan en multitud de archivos PHP a los que se recurre en gran cantidad y con mucha frecuencia, pero también son perceptibles en los demás sitios, ya que raro es el sitio web que no utilice PHP.

Apache mod_fcgid + PHP-FPM en CentOS

En este artículo doy por supuesto que se tiene instalado en el servidor tanto PHP, como Apache y el módulo mod_fcgid

La configuración de mod_fcgid se realiza principalmente a través de diversos archivos de configuración. Por lo tanto es importante saber donde están los archivos de configuración.

Para averiguar la ubicación del archivo de configuración de Apache para tu distribución, utiliza el comando:

# httpd -S

VirtualHost configuration:
[2001:41d0:1:7271::1]:443 is a NameVirtualHost
default server nameserver.com (/etc/httpd/conf/httpd.conf:543)

Como vemos el archivo de configuración de Apache en CentOS se encuentra en la ruta: /etc/httpd/conf/httpd.conf

Apache también tiene que configurarse para utilizar el módulo mod_fcgid, que procese todos los archivos ".php", y mod_fcgid necesita ser avisado de la ubicación del binario de PHP FastCGI, que es php-cgi, y su archivo de configuración se encuentra encuentra en la ruta: /etc/httpd/conf.d/fcgid.conf

Aunque en este proceso no modificaremos el archivo fcgid.conf es bueno que sepamos su ubicación pues tiene varios aspectos de configuración que indican la forma en que trabajará el módulo con diferentes hilos, procesos y tiempos de ejecución.

Otro archivo a tener presente es el master de PHP-FPM que se encuentra en: /etc/php-fpm.conf que tampoco modificaremos en este proceso, pero que de la misma manera que fcgid.conf puede ser configurado según las características de cada servidor.

Los archivos que si vamos a modificar son el httpd.conf en el apartado de cada VirtualHost y el archivo /etc/php-fpm.d/www.conf que es el que maneja los "pool" de cada dominio para el servicio PHP-FPM.

Modificando los archivos httpd.conf y www.conf

El archivo httpd.conf maneja todas las variables del servidor web Apache y, además, puede configurarse de distinta forma para cada dominio alojado en el servidor mediante la directiva <VirtualHost>. Todas las variables que admite quedan fuera de este artículo, así que nos centraremos en modificar una de ellas para que trabaje el proxy_module, añadiendo las siguientes líneas al <VirtualHost> en que deseamos que trabaje en conjunto con PHP-FPM:

SetEnv proxy-nokeepalive 1
<IfModule proxy_module>
ProxyPassMatch ^/(.*\.php(/.*)?)$ fcgi://127.0.0.1:9000/home/usuario/public_html/$1 timeout=600
ProxyTimeout 600
</IfModule>

También se puede hacer de esta manera:

SetEnv proxy-nokeepalive 1
<FilesMatch \.php$>
SetHandler "proxy:fcgi://127.0.0.1:9000"
</FilesMatch>

Siendo 9000 el puerto en que escuchará el servicio PHP-FPM.

El archivo www.conf es el que maneja los pools del servico php-fpm. Para configurarlo y que trabaje con el módulo mod_fcgid añadiremos al final del archivo las siguientes líneas:

;;;;;;;;;;;;;;;;;;; Start a new pool named 'Nombre del dominio'. ;;;;;;;;;;;;;;;;;;
; the variable $pool can we used in any directive and will be replaced by the
; pool name ('Nombre-Dominio' here)

[Nombre-Dominio]

; Unix user/group of processes
; Note: The user is mandatory. If the group is not set, the default user's group
; will be used.

user = usuario
group = apache
listen = 127.0.0.1:9000
listen.backlog = 65535
listen.mode = 0660
listen.allowed_clients = 127.0.0.1
pm = dynamic

pm.max_children = 150
pm.start_servers = 10
pm.min_spare_servers = 8
pm.max_spare_servers = 25
pm.process_idle_timeout =60s
pm.max_requests = 0

rlimit_files = 131072
rlimit_core = unlimited
catch_workers_output = no

listen.owner = usuario
listen.group = apache

chdir = /home/usuario/public_html
slowlog = /var/log/php-fpm/usuario-slow.log

php_admin_value[error_log] = /var/log/php-fpm/usuario-error.log

; Set session path to a directory owned by process user
php_value[session.save_handler] = files
php_value[session.save_path] = /var/lib/php/session
php_value[soap.wsdl_cache_dir] = /var/lib/php/wsdlcache

Cambiaremos:

[Nombre-Dominio] por el nombre que queramos dar al pool (es indiferente pero lo mejor es que esté asociado a cada dominio)

user = usuario por el nombre de usuario del dominio

listen = 127.0.0.1:9000 cambiaremos 9000 por el número del puerto en que queremos que escuche php-fpm

listen.owner = usuario por el nombre de usuario del dominio

También podemos cambiar el valor de los demás parámetros dependiendo de las características de nuestros sitios web. Esta es la configuración que funciona en mi sistema, no doy garantía de que vaya a comportarse igual con otras configuraciones.

Para averiguar si está funcionando escribiremos este script:

<?php

phpinfo();

?>

Lo guardaremos como archivo .php (por ejemplo info.php) y lo subiremos al directorio raíz de nuestro dominio. Si vamos a la URL https://mi-dominio/info.php deberemos ver activado FPM/FastCGI :

info.php

Un ejemplo en vivo en uno de mis dominios: https://pirman.es/info.php

En Apañados.es funciona pero me da error de acceso a la administración de Joomla! y lo tengo desactivado hasta que averigüe porqué (podría ser debido a la URL internacionalizada).

Jesus_Caceres