Dos advertencias aparecen en los registros de muchos sitios web de negocios con mucho tráfico: la de Apache, "server reached MaxRequestWorkers setting", y la de PHP-FPM, "server reached pm.max_children setting". Ambas significan lo mismo: las solicitudes están esperando un worker disponible. El instinto es subir el número y seguir adelante, pero en un servidor con memoria limitada eso cambia páginas lentas por un servidor que usa swap o se queda sin memoria en el peor momento posible. El buen rendimiento de Apache viene de dimensionar MaxRequestWorkers y PHP-FPM según la RAM que realmente tiene. Esta guía recorre ese cálculo para la configuración moderna más común: Apache 2.4 con el MPM event delante de PHP-FPM.
Primero, confirme qué MPM y qué manejador de PHP usa
Los números solo tienen sentido cuando se conoce la arquitectura. apachectl -V muestra el MPM activo en su línea "Server MPM", y en Debian y Ubuntu a2query -M imprime solo su nombre. En los sistemas basados en Red Hat el servicio se llama httpd, pero el rendimiento de httpd sigue las mismas reglas. Luego compruebe cómo se ejecuta PHP: mediante PHP-FPM, normalmente a través de proxy_fcgi, o como mod_php dentro de Apache. La diferencia es grande:
- prefork con mod_php: cada proceso de Apache lleva un intérprete completo de PHP, incluso cuando solo envía una imagen. La memoria por conexión es alta, y MaxRequestWorkers es en la práctica su límite de PHP.
- El MPM event de Apache con PHP-FPM: los hilos de Apache son ligeros y manejan conexiones, archivos estáticos y keep-alive, mientras que PHP se ejecuta en un pool de procesos aparte. Apache puede mantener muchas más conexiones, y pm.max_children de PHP-FPM pasa a ser el ajuste que protege la memoria.
Si un servidor todavía usa prefork con mod_php, pasar a event con PHP-FPM suele ser el cambio individual más eficaz. Eso sí, requiere pruebas, porque las líneas php_value en los archivos .htaccess solo funcionan con mod_php y deben trasladarse al pool de PHP-FPM o a un archivo .user.ini.
Mida el uso de memoria de Apache y el tamaño de los procesos PHP
El dimensionamiento empieza con una medición durante un periodo normal de mucha actividad, no un domingo tranquilo por la mañana. Observe:
- La RAM total y qué más vive en el servidor. Una base de datos, una caché como Redis, los servicios de correo y el sistema operativo necesitan su parte antes de que los workers web reciban algo.
- El tamaño promedio de los procesos de PHP-FPM. ps con la columna rss, filtrado a los procesos php-fpm, da una cifra de trabajo. Use el tamaño típico bajo carga, no el del proceso inactivo más pequeño.
- El uso de memoria de Apache por proceso hijo. Con el MPM event suele ser modesto, porque los hilos dentro de cada hijo comparten memoria.
Apache mod_status con una página server-status, restringida a su propia dirección IP, muestra el scoreboard: cuántos workers están ocupados leyendo, escribiendo o manteniendo conexiones keep-alive. Si la mayoría están en keep-alive, el KeepAliveTimeout está reteniendo espacios para navegadores inactivos.
Dimensionamiento de PHP-FPM pm.max_children
Para PHP-FPM, la fórmula de trabajo es sencilla: la memoria que puede dar a PHP, dividida entre el tamaño promedio de un proceso PHP. Por ejemplo, en un servidor con 8 GB de RAM donde la base de datos, la caché y el sistema necesitan unos 4 GB, quedan aproximadamente 4 GB para PHP. Con unos 100 MB por proceso eso permite unos 40 hijos, y conviene empezar un poco por debajo y observar.
Importan otros dos ajustes. El modo del administrador de procesos: dynamic mantiene un rango de procesos listos, ondemand los inicia solo cuando hacen falta, lo que conviene a muchos sitios pequeños en un servidor, y static mantiene un número fijo, lo que conviene a una sola aplicación con mucho tráfico. Y pm.max_requests, que recicla cada proceso tras un número determinado de solicitudes para que no se acumulen fugas lentas de memoria en los plugins. Tenga en cuenta que el archivo de pool que viene con PHP fija pm.max_children en solo 5, así que un sitio con mucho tráfico que funcione con los valores predeterminados llega muy pronto al límite.
Dimensionamiento de MaxRequestWorkers para el MPM event
Con el MPM event, MaxRequestWorkers es el número total de hilos que pueden atender solicitudes a la vez, y debe caber dentro de ServerLimit multiplicado por ThreadsPerChild. Los valores predeterminados compilados de Apache son 16 procesos de 25 hilos, 400 en total, y los archivos de configuración de las distribuciones suelen fijar valores menores. Como PHP-FPM ya limita el trabajo de PHP, MaxRequestWorkers en un servidor con event puede quedar cómodamente por encima de pm.max_children. Los hilos adicionales cuestan poca memoria y permiten que Apache siga sirviendo imágenes, hojas de estilo y conexiones keep-alive mientras PHP está ocupado. Si sube MaxRequestWorkers más allá de ServerLimit por ThreadsPerChild, suba también ServerLimit y reinicie Apache por completo, porque una recarga graceful no cambia ServerLimit.
Con el MPM prefork el cálculo es más estricto: MaxRequestWorkers multiplicado por el tamaño promedio de un proceso de Apache debe caber en la memoria que queda para Apache, ya que cada worker es un proceso completo.
KeepAlive, tiempos de espera y prueba del resultado
- KeepAliveTimeout. El valor predeterminado de 5 segundos es razonable; los valores largos mantienen espacios abiertos para navegadores que ya terminaron. El MPM event maneja de forma eficiente las conexiones keep-alive inactivas, otra razón para preferirlo.
- Timeout. Un tiempo de espera de solicitud muy largo permite que unos pocos clientes lentos o abusivos ocupen workers. Ajústelo a la solicitud legítima más lenta, como una carga de archivos grande o un informe.
- Un cambio a la vez. Aplique cada cambio con una recarga graceful cuando sea posible, vigile la memoria, el scoreboard y los tiempos de respuesta durante un periodo de mucha actividad, y conserve la configuración anterior para poder revertir.
El mismo enfoque de medir primero se aplica a cualquier proyecto de optimización de Apache, y así empieza nuestro ajuste del rendimiento de Apache. Si las páginas siguen lentas mientras los workers están ociosos, el cuello de botella está en otra parte, normalmente en las consultas a la base de datos o en la propia aplicación, que es donde entra la optimización de MySQL y MariaDB.
Preguntas frecuentes: MaxRequestWorkers
¿Debo simplemente subir MaxRequestWorkers cuando aparece la advertencia?
Solo después de revisar la memoria. Si el servidor tiene margen, un aumento moderado está bien. Si ya está cerca de usar swap, un límite más alto empeora las cosas; la respuesta es menos solicitudes y más rápidas mediante caché, o más memoria.
¿Cuánta RAM necesita un sitio WordPress por proceso PHP?
Varía según los plugins y los temas, y por eso medir sus propios procesos es mejor que cualquier regla general. Las tiendas con mucho tráfico y los constructores de páginas tienden a necesitar notablemente más por solicitud que los sitios de presentación sencillos.
¿Es seguro el MPM event con archivos .htaccess?
Sí. El MPM no cambia cómo funcionan las reglas de reescritura y de acceso en .htaccess. Lo que cambia es cómo se ejecuta PHP, así que lo que hay que comprobar es si los ajustes de PHP en esos archivos deben trasladarse al pool de PHP-FPM.
¿Ve advertencias de MaxRequestWorkers o pm.max_children en un servidor en Los Ángeles o Long Beach? Nuestro servicio de optimización de servidores web Apache empieza con la medición y luego ajusta juntos el MPM, PHP-FPM, la caché y el refuerzo de seguridad. Contáctenos con las advertencias de su registro de errores y la cantidad de RAM del servidor.
¿Cuál es el costo del servidor web Apache?
El software en sí no cuesta nada: Apache HTTP Server es software libre y de código abierto, igual que PHP-FPM, que viene con PHP. En la práctica, el costo del servidor Apache que importa es el hardware y el tiempo que lo rodea. Los workers dimensionados por encima de la RAM disponible llevan al servidor a usar swap, y el atajo habitual es comprar una máquina más grande. Medir el tamaño de los procesos PHP, ajustar pm.max_children y MaxRequestWorkers en consecuencia y añadir caché puede permitir que el servidor existente maneje más tráfico antes de que haga falta más memoria.




