Configuración Detallada de PHP-FPM

Introducción a PHP-FPM

PHP-FPM (PHP FastCGI Process Manager) es un módulo de extensión para PHP diseñado para administrar un conjunto de procesos que manejan las solicitudes de los servidores web. Este componente opera como un gestor de procesos FastCGI y puede integrarse con servidores web como Nginx, Apache u otros.

La función principal de PHP-FPM es gestionar y programar la ejecución de scripts PHP. A través de la creación y administración de un grupo de procesos PHP, este componente puede manejar múltiples solicitudes simultáneamente. Cada proceso dentro del grupo puede procesar una o varias solicitudes PHP, dependiendo de la configuración establecida.

PHP-FPM ofrece características avanzadas como ajuste dinámico de grupos de procesos, límites de solicitudes y controles de tiempo de espera, reinicio de procesos, registro de eventos, y soporte para comunicación entre procesos mediante sockets Unix o TCP/IP, además de gestión basada en archivos y memoria compartida.

Instalación

A partir de PHP 5.3.3, php-fpm se ha incorporado al código principal de PHP, por lo que no requiere instalación por separado. Para habilitar soporte para php-fpm durante la compilación del código fuente de PHP, simplemente utilice la opción --enable-fpm.

Para permitir que Nginx utilice PHP, también es posible instalar el módulo fpm por separado:

yum install php-fpm -y

Inicie el servicio, que por defecto escucha en el puerto 9000:

systemctl start php-fpm

Verifique el estado:

netstat -anpltuo |grep "9000"

Las rutas de instalación predeterminadas para php-fPM son:

/usr/sbin/php-fpm

/etc/php-fpm.conf (configuración global)

/etc/php-fpm.d/www.conf (archivo de configuración predeterminado para el grupo de procesos)

Configuración Detallada de php-fpm

El manual oficial de PHP también proporciona información detallada sobre la configuración: PHP: Configuración - Manual

pid = /usr/local/var/run/php-fpm.pid #Establece el ID del proceso. Debe habilitarse. La ruta anterior es para Mac. Por defecto se encuentra en el directorio de instalación de PHP, en var/run/php-fpm.pid. Por ejemplo, en CentOS: /usr/local/php/var/run/php-fpm.pid

error_log = /usr/local/var/log/php-fpm.log #Ruta del registro de errores. La ruta anterior es para Mac. Por defecto se encuentra en el directorio de instalación de PHP, en var/log/php-fpm.log. Por ejemplo, en CentOS: /usr/local/php/var/log/php-fpm.log

log_level = notice #Nivel de registro. Determina el nivel de detalle registrado en php-fpm.log. Los niveles disponibles son: alerta (requiere atención inmediata), error (situaciones de error), warning (advertencias), notice (información importante), debug (información de depuración). Valor predeterminado: notice.

emergency_restart_threshold = 60 emergency_restart_interval = 60s #Indica que si durante el intervalo especificado aparecen más procesos php-cgi con errores SIGSEGV o SIGBUS que el umbral establecido, php-fPM reiniciará优雅mente. Generalmente es mejor mantener los valores predeterminados. 0 indica 'deshabilitar esta función'. Valor predeterminado: 0 (deshabilitado).

process_control_timeout = 0 #Tiempo de espera para que los procesos secundarios reciban señales de reutilización del proceso principal. Unidades disponibles: s (segundos), m (minutos), h (horas), d (días). Unidad predeterminada: s (segundos). Valor predeterminado: 0.

daemonize = yes #Ejecutar fPM en segundo plano. El valor predeterminado es yes. Para depuración, puede cambiarse a no. En FPM, se pueden ejecutar múltiples grupos de procesos con configuraciones diferentes. Estas configuraciones pueden establecerse individualmente para cada grupo de procesos.

listen = 127.0.0.1:9000 #Puerto que escucha fPM, es decir, la dirección que Nginx utiliza para procesar PHP. Generalmente el valor predeterminado es suficiente. Los formatos disponibles son: 'ip:puerto', 'puerto', '/ruta/al/socket/unix'. Cada grupo de procesos requiere esta configuración. Si Nginx y PHP están en máquinas diferentes (distribuido), configure la IP aquí.

listen.backlog = -1 #Tamaño de la cola de semi-conexiones para listen. -1 significa sin límite, determinado por el sistema operativo. Esta línea puede dejarse comentada. Para más información sobre backlog: http://www.3gyou.cc/?p=41

listen.allowed_clients = 127.0.0.1 #Lista blanca de IPs permitidas para acceder a los procesos FastCGI. Establecer 'any' para no limitar IP. Si desea que otros hosts Nginx accedan a este proceso FPM, la configuración de listen debe establecerse en una IP accesible localmente. El valor predeterminado es 'any'. Cada dirección está separada por comas. Si no se establece o está vacío, se permite cualquier servidor.

listen.owner = www listen.group = www listen.mode = 0666 #Opciones de configuración para socket Unix. Si se utiliza el modo TCP, estas líneas deben comentarse.

user = www group = www #Usuario y grupo del sistema bajo los que se inician los procesos. El usuario debe establecerse obligatoriamente. Si no se establece el grupo, se utiliza el grupo del usuario por defecto.

pm = dynamic #Modo de inicio de procesos de php-fPM. Puede establecerse en static, dynamic o ondemand. #Si se elige static, el número de procesos es fijo, especificado por pm.max_children. #Si se elige dynamic, el número de procesos varía dinámicamente según los siguientes parámetros:

pm.max_children = 50 #Número máximo de procesos secundarios pm.start_servers = 2 #Número de procesos al inicio. Valor predeterminado: min_spare_servers +(max_spare_servers - min_s_spare_servers) / 2 pm.min_spare_servers = 1 #Número mínimo garantizado de procesos inactivos. Si los procesos inactivos son menores a este valor, se crean nuevos procesos secundarios pm.max_spare_servers = 3 #Número máximo garantizado de procesos inactivos. Si los procesos inactivos superan este valor, se eliminan

pm.max_requests = 500 #Número de solicitudes que cada proceso secundario puede procesar antes de ser reiniciado. Muy útil para módulos de terceros que puedan tener fugas de memoria. Si se establece en '0', el proceso acepta solicitudes indefinidamente. Equivalente a la variable de entorno PHP_FCGI_MAX_REQUESTS. Valor predeterminado: 0.

pm.status_path = /status #URL de la página de estado de FPM. Si no se establece, no se puede acceder a la página de estado. Valor predeterminado: none. Utilizado por monitoreo como munin.

ping.path = /ping #URL para ping de monitoreo de FPM. Si no se establece, no se puede acceder a la página de ping. Se utiliza para detectar externamente si FPM está activo y respondiendo. Debe comenzar con una barra diagonal (/).

ping.response = pong #Define la respuesta para la solicitud ping. Devuelve texto en formato HTTP 200 text/plain. Valor predeterminado: pong.

access.log = log/$pool.access.log #Registro de acceso para cada solicitud. Predeterminado: deshabilitado.

access.format = "%R - %u %t \"%m %r%Q%q\" %s %f %{mili}d %{kilo}M %C%%" #Formato del registro de acceso.

slowlog = log/$pool.log.slow #Registro de solicitudes lentas. Requiere配合request_slowlog_timeout. Predeterminado: deshabilitado.

request_slowlog_timeout = 10s #Cuando una solicitud excede este tiempo de espera, la información completa de la pila de llamadas de PHP se escribe en el registro lento. Establecer en '0' para 'deshabilitar'.

request_terminate_timeout = 0 #Tiempo de espera para abortar una sola solicitud. Puede ser útil para scripts que no se detienen debido a razones especiales, a pesar de la configuración de 'max_execution_time' en php.ini. Establecer en '0' para 'deshabilitar'. Cuando aparecen errores 502 con frecuencia, puede intentar modificar esta opción.

rlimit_files = 1024 #Límite rlimit para descriptores de archivos abiertos. Valor predeterminado: definido por el sistema. El límite predeterminado de descriptores abiertos es 1024, que puede verificarse con ulimit -n y modificarse con ulimit -n 2048.

rlimit_core = 0 #Límite máximo rlimit para core. Valores disponibles: 'unlimited', 0 o enteros positivos. Valor predeterminado: definido por el sistema.

chroot = #Directorio Chroot al inicio. El directorio definido debe ser una ruta absoluta. Si no se establece, no se utiliza chroot.

chdir = #Directorio de inicio. Al iniciar, se cambia automáticamente a este directorio. Debe ser una ruta absoluta. Valor predeterminado: directorio actual o / directorio (al usar chroot).

catch_workers_output = yes #Redirige stdout y stderr durante la ejecución al archivo de registro de errores principal. Si no se establece, stdout y stderr se redirigirán a /dev/null según las reglas FastCGI. Valor predeterminado: vacío.

Configuración de Entorno de Prueba

[www]
user = nobody               #Usuario y grupo del sistema que inicia los procesos. El usuario es obligatorio, el grupo no. 'nobody' es cualquier usuario
group = nobody

listen = [::]:9000          #IP y puerto de escucha. [::] representa cualquier IP
chdir = /app                #Directorio al que se cambiará al iniciar el programa (ruta relativa al directorio actual o al directorio raíz después de chroot)

pm = dynamic                #Controla cómo el administrador de grupos de procesos gestiona el número de procesos secundarios
pm.max_children = 16        #Número máximo de procesos secundarios que pueden existir simultáneamente
pm.start_servers = 4        #Número de procesos secundarios creados al inicio
pm.min_spare_servers = 2    #Número mínimo de procesos en estado 'inactivo'. Si el número de procesos inactivos es menor a este valor, se crearán procesos adicionales
pm.max_spare_servers = 16   #Número máximo de procesos inactivos. Si el número de procesos inactivos supera este valor, se eliminarán procesos adicionales

catch_workers_output = Yes  #Redirige stdout y stderr de los trabajadores al registro de errores principal. Si no se establece, se redirigirán a /dev/null según las especificaciones FastCGI

Redirección de Solicitudes a PHP-FPM

server {
        listen       80;
        server_name  localhost;
        index index.html index.php;
        root /data/www;

        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   /usr/share/nginx/html;
        }

        location / {
                index  index.html index.htm index.php;
                # Redirige todo lo que no sea un archivo real a index.php
                try_files $uri $uri/ /index.php$is_args$args;
        }

        # Redirige las solicitudes HTTP al grupo de procesos PHP-FPM para su procesamiento
       location ~ \.php$ {
            include fastcgi_params;
            fastcgi_pass   127.0.0.1:9000;
            fastcgi_index  index.php;
            fastcgi_param  SCRIPT_FILENAME  /data/www$fastcgi_script_name;
            include        fastcgi_params;
        }
}

Asignación de Procesos en PHP-FPM

En modo FastCGI, PHP inicia múltiples procesos php-fPM para recibir solicitudes de Nginx. Sin embargo, ¿más procesos significan mayor velocidad? No necesariamente. Depende de la configuración de la máquina y el volumen de negocio.

Veamos dónde se configura la asignación de procesos:

pm = static | dynamic | ondemand

PM puede configurarse en estos 3 modos, siendo los más comunes los dos primeros.

Modo pm = static

En el modo pm = static, el número de procesos secundarios php-fPM es fijo. Solo el parámetro pm.max_children = 50 es efectivo. Al iniciar php-fPM, se iniciarán todos los procesos (1 principal + 50 secundarios) simultáneamente.

Modo pm = dynamic

El modo pm = dynamic indica que la asignación de procesos es dinámica y varía según el volumen de solicitudes. Está determinado por los parámetros pm.max_children, pm.start_servers, pm.min_spare_servers, y pm.max_spare_servers.

pm.max_children = 50 es el número máximo de procesos secundarios que pueden crearse. Debe establecerse. Esto significa que solo pueden existir 50 procesos secundarios como máximo.

pm.start_servers = 20 es el número de procesos secundarios creados junto con php-fPM al inicio. Valor predeterminado: min_spare_servers + (max_spare_servers - min_s_spare_servers) / 2. Esto significa que se iniciarán 20 procesos secundarios al principio.

**pm.min_spare_servers = 10**Establece el número mínimo de procesos php-fPM inactivos cuando el servidor está inactivo. Debe establecerse. Si el servidor está inactivo y hay menos de 10 procesos, se crearán nuevos procesos para alcanzar este mínimo.

**pm.max_spare_servers = 30**Establece el número máximo de procesos php-fPM inactivos cuando el servidor está inactivo. Debe establecerse. Si el número de procesos inactivos supera 30, se cerrarán procesos adicionales para mantener este máximo.

¿Elegir static o dynamic?

Muchas personas dudan sobre qué opción elegir.

El principio general es: el modo dinámico es adecuado para máquinas con poca memoria, asignando procesos flexiblemente y ahorrando memoria. El modo estático es adecuado para máquinas con mucha memoria, ya que la creación y eliminación dinámica de procesos consume recursos del servidor.

Si tiene mucha memoria (8-20 GB), considerando que cada proceso php-fPM ocupa aproximadamente 20 MB, 100 procesos ocuparía 2 GB de memoria. En este caso, puede habilitar el modo estático. Si la memoria es limitada (por ejemplo, 256 MB), debe tener cuidado en la configuración, ya que otros procesos también consumen memoria. En este caso, el modo dinámico es la mejor opción, por ejemplo: pm.max_children = 8, que ocupa aproximadamente 160 MB de memoria y puede variar según sea necesario, siendo suficiente para sitios web con tráfico moderado.

Consulta de Registro Lento

A veces nos enfrentamos a problemas con errores 500 y 502. Cuando Nginx recibe estos códigos de error, podemos determinar que hay algún problema con el procesamiento PHP por parte de php-fPM en el backend, como errores de ejecución o exceder el tiempo de ejecución.

En este caso, podemos habilitar la función de registro lento:

slowlog = /usr/local/var/log/php-fpm.log.slow request_slowlog_timeout = 15s

Cuando una solicitud excede el tiempo de espera establecido de 15 segundos, la información completa de la pila de llamadas de PHP se escribe en el registro lento.

El registro lento de php-fPM registra el ID del proceso, el nombre del script y la función específica en qué archivo y línea que tardó demasiado tiempo:

[21-Nov-2013 14:30:38] [pool www] pid 11877 script_filename = /usr/local/lnmp/nginx/html/www.quancha.cn/www/fyzb.php [0xb70fb88c] file_get_contents() /usr/local/lnmp/nginx/html/www.quancha.cn/www/fyzb.php:2

A través de este registro, podemos saber que la función file_get_contents en la línea 2 tiene algún problema, lo que nos permite rastrear y resolver el problema.

Documentos de referencia:

Modos de Operación de PHP-FPM_php-fpm-CSDN Blog

Explicación Detallada de PHP-FPM-CSDN Blog

https://www.cnblogs.com/followyou/p/9460058.html

Etiquetas: PHP FPM Nginx FastCGI configuración de servidor

Publicado el 7-25 10:37