...

Colas de peticiones PHP y límites de procesamiento: configuración óptima para servidores estables

Las colas de peticiones PHP limitan el número de peticiones que tu servidor procesa al mismo tiempo y, por tanto, determinan el tiempo de respuesta, la tasa de errores y la experiencia del usuario. Le mostraré cómo Límites de procesamiento y eliminar los cuellos de botella y lograr una entrega coherente mediante parámetros armonizados.

Puntos centrales

Para que puedas ponerte manos a la obra de inmediato, te resumo los tornillos de ajuste más importantes para PHP-FPM juntos.

  • pm.max_hijos: Calcula el límite superior de procesos PHP simultáneos para ajustarlo a la RAM.
  • lista.atraso: Maximiza el almacenamiento en búfer a corto plazo de los intentos de conexión durante los picos de carga.
  • pm.max_requestsRecicle los procesos regularmente para evitar fugas de memoria e hinchazón.
  • Tiempos muertos: establece request_terminate_timeout, max_execution_time y los tiempos de espera del servidor web de forma coherente.
  • Métricasmax children reached, comprueba la cola de escucha y los slowlogs continuamente.

Me centro en ratios claros y efectos mensurables para que cada ajuste de Límites sigue siendo rastreable. Para cada cambio, controlo los registros y los tiempos de respuesta antes de planificar el siguiente paso y aumentar o disminuir gradualmente los valores. De esta forma, evito efectos secundarios como el intercambio de memoria, que puede Cola mucho más tiempo. Con este planteamiento, controlo los picos de carga y mantengo estables los tiempos de respuesta. El objetivo es lograr una utilización equilibrada de la capacidad que Recursos eficientemente sin sobrecargar el host.

Cómo funciona PHP Request Queueing en PHP-FPM

Cada solicitud HTTP entrante requiere su propio Trabajador, y un trabajador sólo atiende una petición a la vez. Si todos los procesos están ocupados, las llamadas posteriores acaban en el Cola y esperar hasta que un proceso quede libre. Si esta cola crece, los tiempos de respuesta aumentan y se producen errores como 502/504 con más frecuencia. Por lo tanto, presto atención a una relación razonable entre el número de procesos y la memoria disponible en lugar de centrarme ciegamente en el paralelismo máximo. De este modo, consigo una tasa de rendimiento constante sin RAM o CPU se separan.

Seleccionar limpiamente los modos del gestor de procesos

Además de los valores límite, el modo pm capacidad de respuesta y consumo de recursos:

  • pm = dinámicoDefino start_servers, min_spare_servers y max_spare_servers. Este modo es mi estándar para cargas variables porque reacciona rápidamente a los aumentos y mantiene los procesos calientes listos.
  • pm = a la cartaLos procesos sólo se crean cuando es necesario y se terminan después de process_idle_timeout. Esto ahorra RAM para accesos poco frecuentes (admin, staging, cron endpoints), pero puede provocar una pérdida de RAM en caso de picos repentinos. Arranques en frío y mayor latencia. Por eso lo uso de forma selectiva y con una generosa reserva.
  • pm = estáticoUn número fijo de procesos. Ideal si tengo un límite superior duro y latencias especialmente previsibles (por ejemplo, proxy L7 frente a unos pocos puntos finales, pero críticos). La necesidad de RAM es claramente calculable, pero los procesos no utilizados ocupan memoria.

Yo decido qué modo se adapta mejor al perfil de cada pool. Suelo utilizar el modo dinámico para los frontales con cargas variables, el modo bajo demanda para los grupos de servicios públicos y el modo estático para los servicios dedicados de latencia crítica.

Determinar pm.max_children correctamente

La palanca más importante es pm.max_hijos, porque este valor define cuántas peticiones pueden ejecutarse simultáneamente. Calculo el tamaño inicial usando la regla empírica (RAM libremente disponible - 2 GB de reserva) dividido por la memoria media por proceso PHP. Como suposición aproximada, utilizo 40-80 MB por proceso e inicialmente comienzo con 200-300 procesos en un host de 32 GB. Bajo carga real, aumento o disminuyo gradualmente y compruebo si el tiempo de espera de los Cola y el porcentaje de error disminuye. Si desea profundizar, puede encontrar información sobre los valores de inicio y límite en Optimizar pm.max_children.

Coordinar los valores iniciales, de reserva y de retraso

He puesto pm.iniciar_servidores a alrededor del 15-30 por ciento de pm.max_children para que haya suficientes procesos disponibles al inicio y no se produzcan arranques en frío. Con pm.min_spare_servers y pm.max_spare_servers, defino una ventana razonable de procesos libres para que las nuevas peticiones no esperen y, al mismo tiempo, no haya tiempos muertos innecesarios que ocupen memoria. Listen.backlog es especialmente importante: Este búfer del kernel retiene brevemente los intentos de conexión adicionales cuando todos los trabajadores están ocupados. Para los picos de carga, establezco valores altos (por ejemplo, 65535) para que el cola no se detiene ante el pool de FPM. Encontrará información más detallada sobre la interacción entre el servidor web, el flujo ascendente y los búferes en la descripción general de Cola de servidores web.

Limitar los tiempos de ejecución de las solicitudes y reciclar los procesos

Evito las sobrecargas de memoria con pm.max_requests, que reinicia cada proceso después de X peticiones. Las aplicaciones discretas suelen funcionar bien con 500-800. Si se sospecha que hay fugas de memoria, las reduzco a 100-200 y observo el efecto. Además, request_terminate_timeout encapsula los valores atípicos terminando las peticiones extremadamente largas después de un tiempo fijo. La consistencia es importante: mantengo el max_execution_time de PHP y los tiempos de espera del servidor web en el mismo corredor para que una capa no termine antes que la otra. Esta interacción mantiene el Trabajador libre y protege la piscina de la congestión.

Hacer visibles las colas: Registros y métricas

Leo regularmente los registros de FPM y presto atención a máximo de niños alcanzados, porque esta entrada indica que se ha alcanzado el límite superior de los procesos. Al mismo tiempo, monitorizo la cola de escucha, que revela una acumulación creciente en el búfer de entrada. En combinación con request_slowlog_timeout, obtengo trazas de pila de los puntos lentos del código y aíslo los frenos de la base de datos o de la API. Correlaciono upstream_response_time de los registros del servidor web con request_time y los códigos de estado para acotar el origen de los tiempos de respuesta largos. Esto me permite reconocer si el cuello de botella en PHP-FPM, el Base de datos o la red ascendente.

Perfiles de carga de trabajo: Limitado por CPU vs. Limitado por E/S

Para los procesos que consumen mucha CPU, escalo el Paralelismo Soy prudente y me oriento mucho por el número de vCPU, porque los procesos adicionales apenas aportan rendimiento. Si se trata principalmente de una carga IO con accesos a bases de datos o API externas, puedo permitir más procesos siempre que el presupuesto de RAM sea suficiente. Las compras electrónicas se benefician de tiempos de espera más largos (por ejemplo, 300 s) para completar los métodos de pago sin cancelaciones. Intercepto las ventas flash poniendo listen.backlog alto y aumentando la ventana de reserva. La información sobre el equilibrio entre el número de procesos y el rendimiento del host se incluye en la guía de PHP-Workers como cuello de botella.

Cálculos y dimensionamiento de muestras

Primero calculo la memoria por proceso y luego deduzco una Límite superior off. A continuación, hago pruebas con carga real y observo si la cola disminuye y el rendimiento aumenta. Los valores iniciales conservadores reducen el riesgo de intercambio y mantienen el tiempo de respuesta uniforme. A continuación, voy refinando en pequeños pasos para estar seguro de notar cualquier efecto secundario. La siguiente tabla ofrece orientación sobre los valores iniciales y los efectos en el Cola.

Parámetros Efecto Valor inicial (ejemplo) Nota
pm.max_hijos Máximo simultáneo Procesos 200-300 (con 32 GB) Comparar con el presupuesto de RAM y el tamaño del proceso
pm.iniciar_servidores Número inicial de trabajadores 15-30 % de max_children Evite los arranques en frío, pero reduzca al mínimo el ralentí.
pm.min_servidores_de_repuesto Gratis Trabajador Mínimo z. B. 20 Inclusión directa de nuevas solicitudes
pm.max_servidores_servicio Máximo de trabajadores libres z. B. 40 Limitar el consumo de RAM de los procesos inactivos
lista.atraso Búfer del núcleo para intentos de conexión 65535 Amortiguar los picos de carga y reducir las interrupciones de conexión
pm.max_requests reciclaje Intervalo 500-800, con fugas 100-200 Minimiza la saturación de memoria y los cuelgues
request_terminate_timeout Límite duro de solicitudes 300-600 s Consistente con PHP y los tiempos de espera del servidor web

Plantillas prácticas para pools PHP FPM

Para una tienda con muchos accesos de lectura fijo moderado Cifras del proceso y aumentar la ventana libre para que las peticiones no se pongan en cola. Para las páginas de contenido con almacenamiento en caché, un número significativamente menor de trabajadores suele ser suficiente siempre y cuando NGINX o Apache entreguen el contenido estático de manera eficiente. Separo las configuraciones multi-pool según las partes de la aplicación que tienen diferentes perfiles de memoria para que ningún pool pesado desplace a los demás. Defino pools separados con sus propias reglas de tiempo de espera para los cron o queue workers. Así mantengo la interactividad Tráfico gratuito y no ralentiza ninguna acción del usuario.

Tiempos de espera del servidor web, upstream y sockets

Considero FastCGI y proxy tiempos de espera de Nginx o Apache en la misma ventana que los tiempos de espera de FPM para que ninguna capa termine demasiado pronto. Prefiero los sockets Unix a TCP si ambos servicios se ejecutan en el mismo host, porque la latencia es mínima. Para configuraciones distribuidas, utilizo TCP con valores de keepalive estables y un pool de conexiones suficientemente grande. Para un alto paralelismo, nginx sincroniza worker_connections y los valores de backlog de FPM. Esto asegura que las redirecciones sigan siendo rápidas y evito el tiempo de inactividad debido a conexiones demasiado apretadas. aguas arriba-límites.

Caché, OPCache y base de datos como palancas

Resuelvo muchos problemas de los servidores reduciendo las operaciones costosas y minimizando el Tiempo de respuesta inferior. Enciendo OPCache, aumento el límite de memoria de la caché de forma sensata y aseguro un alto índice de aciertos de la caché. Para obtener resultados recurrentes, utilizo la caché de aplicación para que los procesos PHP se completen más rápidamente. En cuanto a la base de datos, optimizo las consultas lentas y activo cachés de consulta adecuadas al sistema utilizado. Cada milisegundo ahorrado reduce la carga de la base de datos. Cola y aumenta el rendimiento por trabajador.

Mecanismos de emergencia y reinicios seguros

Activo umbral_de_reinicio_de_emergencia y emergency_restart_interval para que el maestro FPM se reinicie si demasiados hijos se bloquean en rápida sucesión. Este reinicio controlado evita reacciones en cadena y mantiene el servicio disponible. Al mismo tiempo, establezco límites claros para la memoria y el número de procesos para evitar escaladas. Las comprobaciones de estado en el lado ascendente eliminan automáticamente los backends defectuosos del grupo y reducen las tasas de error. Esto mantiene el Disponibilidad mientras investigo la causa real.

Ajustar el sistema operativo y los límites de systemd

De modo que lista.atraso realmente surte efecto, ajusto los límites del kernel. El valor net.core.somaxconn del sistema operativo debe ser al menos tan alto como el backlog establecido, de lo contrario el sistema corta la cola. También compruebo el número de descriptores de archivo permitidos: En el pool FPM puedo establecer rlimit_files, a nivel de servicio aseguro LimitNOFILE (systemd) y a nivel de kernel fs.file-max. El servidor web necesita reservas similares para que no alcance antes sus límites.

Para latencias más estables, reduzco vm.swappiness, para que el núcleo no desplace prematuramente las páginas de memoria utilizadas activamente. En configuraciones de latencia crítica, desactivo Páginas enormes transparentes, para evitar fallos de página largos. Si FPM funciona vía TCP, también sincronizo los parámetros net.ipv4.tcp_max_syn_backlog y reuse/keepalive. Estos detalles del sistema operativo parecen poco llamativos, pero deciden si las colas suave expiran o si las conexiones ya han sido rechazadas antes de FPM.

Medir la carga de memoria por proceso

En lugar de hacer estimaciones generalizadas, mido la Consumo real por trabajador bajo carga real. Utilizo herramientas como ps, smem o pmap, filtro para php-fpm children y promedio los valores RSS mientras se ejecutan las peticiones. Es importante tener en cuenta el uso compartido de OPCache: la memoria compartida no se cuenta varias veces. Derivo pm.max_children del valor promediado y también planifico una reserva para que la máquina no se encuentre con un cuello de botella incluso durante los picos. Intercambio se inclina.

Repito esta medición después de cambios de función o de versión. Nuevas funciones, más dependencias o cambios en los marcos de trabajo pueden aumentar significativamente la huella por proceso. Esto mantiene el número de procesos realista y la cola corta.

PHP FPM estado, ping y métricas en vivo

Para una evaluación rápida de la situación, activo pm.status_path y un Ping endpoint (ping.path/ping.response). Puedo ver cifras clave como la conexión aceptada, la longitud de la cola de escucha, los procesos inactivos/ocupados, el número máximo de hijos alcanzados y su progreso. Leo estos valores periódicamente y establezco valores umbral: si la cola de escucha aumenta permanentemente, aumento los procesos o elimino la causa de las peticiones lentas. Si el número máximo de niños alcanzados aumenta mientras que la inactividad se mantiene baja, el pool es demasiado pequeño o está bloqueado por corredores largos.

También separo pools con perfiles diferentes para que los picos en un área (por ejemplo, las importaciones de API) no pongan de rodillas al tráfico interactivo. Para los casos de diagnóstico, aumento temporalmente el log_level y dejo que el slowlog capture más muestras, pero luego lo vuelvo a reducir para mantener baja la carga de E/S.

Cargas, almacenamiento en búfer y solicitudes de gran volumen

Las subidas grandes pueden atascar innecesariamente a los trabajadores si PHP tiene que leer primero el cuerpo de la petición. Me aseguro de que el servidor web topes (por ejemplo fastcgi_request_buffering para NGINX), para que FPM sólo se inicie cuando el cuerpo esté completo. Esto significa que ningún trabajador se bloquea durante la carga. Uso client_max_body_size, post_max_size y max_input_time para controlar lo grandes y largas que pueden ser las peticiones sin poner en peligro los endpoints. Si hay archivos en medio, asigno memoria temporal suficientemente rápida (SSD) para evitar atascos de búfer.

Para endpoints con cuerpos muy grandes (por ejemplo, exportaciones/importaciones), defino pools dedicados con sus propios tiempos de espera y menos paralelismo. Esto deja libres a los trabajadores estándar y a los Cola de las acciones importantes del usuario.

Conexiones de bases de datos y límites del pool

Incluso el mejor ajuste de FPM es inútil si el Base de datos previamente limitada. Alineo el número máximo de procesos PHP simultáneos con la capacidad real disponible de la BD. Para conexiones persistentes o pools de conexiones, me aseguro de que la suma de todos los pools es en max_connections permanece. Si hay muchas consultas cortas, ayuda a limitar el paralelismo PHP moderadamente para que la DB no thrash entre miles de sesiones.

Las transacciones lentas provocan rápidamente un atasco en la cola de FPM. Por tanto, analizo los tiempos de espera de los bloqueos, el uso de índices y los planes de consulta. Cada reducción en el tiempo de ejecución de la base de datos reduce inmediatamente el tiempo de ejecución de PHP.Duración del documento y reduce la longitud de las colas.

Lanzamientos y despliegues sin picos

Cuando despliego nuevas versiones, evito las cachés frías y las tormentas de procesos. Utilizo recargar en lugar de reinicios duros, para que las peticiones de los trabajadores existentes terminen limpiamente (tenga en cuenta process_control_timeout). Caliento el OPCache en una fase temprana ejecutando rutas críticas una vez antes de cambiar o trabajando con precarga. Esto evita que muchos trabajadores analicen archivos de clase al mismo tiempo y que el Tiempo de respuesta aumenta a pasos agigantados.

Con estrategias azul/verde o canario, aumento gradualmente la carga y controlo las páginas de estado. Sólo cuando la cola, la tasa de errores y las latencias se mantienen estables, aumento la proporción de tráfico. Este enfoque controlado protege contra los picos de carga durante el despliegue.

Especialidades en contenedores y máquinas virtuales

En los contenedores, la percepción Volumen total de almacenamiento a menudo inferior a la que informa el host. Yo alineo pm.max_children estrictamente al límite del cgroup y planeo una reserva contra el asesino OOM. Los límites de memoria en PHP (memory_limit) y la huella por proceso deben coincidir, de lo contrario un solo valor atípico es suficiente para terminar el contenedor.

Si no hay intercambio en el contenedor, es más probable que se produzcan cancelaciones bruscas. Por eso mantengo los procesos conservadores, activo el reciclaje y controlo los picos RSS en la carga de producción. En este caso, varios pools magros suelen ser más robustos que un pool grande y monolítico.

Degradación y contrapresión controlables

Si el Cola Me baso en la degradación controlada: entrego deliberadamente 503 con reintento después para los puntos finales no críticos en caso de sobrecarga, reduzco las funciones caras (por ejemplo, las búsquedas en directo) y limito el acceso paralelo a los puntos críticos. Así mantengo la capacidad de respuesta del sistema mientras rectifico la causa, en lugar de que todos los usuarios sufran tiempos de espera.

Brevemente resumido

Traigo Cola de peticiones PHP bajo control ajustando inteligentemente el número de procesos concurrentes al presupuesto de RAM y al tipo de carga. Los valores de backlog altos amortiguan los picos, los tiempos de espera a todos los niveles encajan perfectamente y el reciclaje elimina los problemas de memoria. Los registros y las métricas me muestran si la cola está creciendo, dónde se atascan las peticiones y cuándo debo reforzarla. Con ajustes cuidadosos y un almacenamiento en caché específico, reduzco el tiempo de procesamiento por solicitud y aumento el rendimiento. De este modo, los servidores ofrecen un rendimiento constante y evitan costosos problemas de memoria. Tiempos muertos en la vida cotidiana.

Artículos de actualidad

Hyperthreading de CPU en servidores de alojamiento con núcleos lógicos
Servidores y máquinas virtuales

Hyperthreading de CPU en hosting: ventajas y riesgos

El hyperthreading de la CPU en hosting aumenta el rendimiento de los núcleos lógicos, pero alberga riesgos. Aprenda a ajustar el servidor para obtener un rendimiento óptimo del servidor web.