Actualmente tengo un servidor Apache2 que se ejecuta con mpm-prefork
y mod_php
en un VPS OpenVZ con 512M de RAM real / 1024M (sin intercambio). Después de ejecutar algunas pruebas, descubrí que el tamaño máximo de proceso que Apache obtiene es de 23M, así que lo configuré MaxClients
en 25 (23M x 25 = 575 MB, está bien para mí). Decidí ejecutar algunas pruebas de carga en mi servidor, y los resultados me dejaron perplejo.
Estoy usando ab
en mi máquina de escritorio solicitando la página principal de un blog de WordPress.
Cuando corro ab
con 24 conexiones concurrentes, todo parece estar bien. Claro, la CPU sube, la RAM libre baja y el resultado es un tiempo de respuesta de 2-3 segundos por solicitud.
Pero si ejecuto ab
con 25 conexiones concurrentes (el límite de mi servidor), Apache simplemente se cuelga después de un par de segundos. Comienza a procesar las solicitudes, luego deja de responder, la CPU vuelve al 100% de inactividad y ab
agota el tiempo de espera. El registro de Apache dice que llegó MaxClients
.
Cuando esto sucede, Apache se mantiene encerrado con 25 procesos en ejecución (todos están en "W" si verifico el estado del servidor) y solo después de la TimeOut
configuración, los procesos comienzan a morir y el servidor comienza a responder nuevamente (en mi caso, está configurado a 45).
Mi pregunta: ¿es ese comportamiento esperado? ¿Por qué Apache simplemente muere cuando llega MaxClients
? Si funciona con 24 conexiones, ¿no debería funcionar con 25, simplemente tomando más tiempo para responder cada solicitud y haciendo cola con el resto?
Me parece un poco extraño que cualquier niño corriendo ab
solo pueda matar un servidor web simplemente configurando las conexiones concurrentes a los servidores MaxClients
.
fuente
Lo que está sucediendo aquí es que tiene 25 hilos capaces de aceptar conexiones, y está enviando 26 solicitudes concurrentes. Esa última solicitud se encuentra en la cola de socket según el tamaño de su cartera de pedidos.
El segundo problema es que lo que sea que esté ejecutando, que demore de 2 a 3 segundos, demore lo suficiente como para responder que las 25 conexiones concurrentes lo están ralentizando. sleep (1) podría funcionar, pero, algo en lo que está haciendo el bloqueo de archivos o el bloqueo de tablas desde mysql, cada solicitud paralela puede estar esperando antes de completarse hasta que lleguen al tiempo de espera de 45 segundos.
23mb suena pequeño para un proceso de apache con mod_php y cualquier módulo cargado, por lo tanto, sospecho que podría estar viendo que esos procesos de apache toman un poco más de memoria RAM a medida que se ejecuta su aplicación. Realmente no puedes hacer matemáticas con MaxClients y una memoria así ... estará algo cerca, pero nunca se sabe.
Hay una máquina, procesos de 56M y 49M.
otra maquina:
otra maquina:
Por lo tanto, el uso de la memoria depende mucho de la tarea, qué módulos se cargan, etc. En los dos últimos, creo que hemos deshabilitado pdo y pdo_mysql ya que esa aplicación no los usa.
La verdadera pregunta es, ¿qué estás haciendo que te toma 3 segundos? En el mundo de hoy, eso es una eternidad y se considera una aplicación de 'bloqueo'. Apache normalmente no morirá, pero dejará esos subprocesos en la cola de pedidos pendientes hasta que pueda atenderlos o se agote el tiempo de espera de las solicitudes de espera. Creo que su aplicación probablemente está causando que apache se agote. Pruébelo en una página que contenga solo phpinfo (); y ver si los resultados son los mismos.
fuente