PHP-FPM frente a PHP-CGI: qué cambia en producción
Por qué la gestión de procesos importa más que la versión de PHP cuando un sitio empieza a devolver errores 502 y 504.
En esta página (5)
La mayoría de los sitios PHP lentos o inestables que me piden revisar no tienen nada malo en el código. El problema es cómo se inician, comparten y limitan los procesos de PHP.
La diferencia en un párrafo
Con el CGI clásico, el servidor web inicia un proceso PHP nuevo por cada petición y lo descarta después. Es simple y seguro, y lento. PHP-FPM (FastCGI Process Manager) mantiene un pool de workers de larga vida que atienden muchas peticiones, lo que permite caché de opcode, conexiones persistentes y un uso de memoria predecible.
Los pools son la verdadera ventaja
Cada sitio puede tener su propio pool con su propio usuario, límites y ajustes.
; /etc/php/8.3/fpm/pool.d/example.conf
[example]
user = example
group = example
listen = /run/php/example.sock
listen.owner = www-data
listen.group = www-data
pm = dynamic
pm.max_children = 20
pm.start_servers = 4
pm.min_spare_servers = 2
pm.max_spare_servers = 6
pm.max_requests = 500
request_slowlog_timeout = 5s
slowlog = /var/log/php-fpm/example-slow.log
Dimensionar pm.max_children
No adivines. Mide la memoria media de un worker bajo carga real y divide la memoria disponible entre ese número.
ps --no-headers -o rss -C php-fpm8.3 | awk '{s+=$1; n++} END {print s/n/1024 " MB avg"}'
Si el resultado es 60 MB y puedes dedicar 2 GB, el techo ronda los 30 workers. Superarlo cambia peticiones lentas por swapping, que es peor.
Leer los síntomas
- 502 Bad Gateway suele significar que el pool se cayó, falta el socket o los permisos del socket son incorrectos.
- 504 Gateway Timeout suele significar que todos los workers están ocupados. Revisa
pm.max_childreny el slow log antes de subir los tiempos de espera. - La memoria que crece suele resolverse con un
pm.max_requestsrazonable, que recicla los workers.
Lista de comprobación
- Un pool y un usuario de sistema por sitio.
- OPcache activado y dimensionado para el código.
pm.max_childrenderivado de la memoria medida.- El slow log activado y realmente leído.
Aún no hay comentarios. Sé el primero en comentar.