Ejecuto una aplicación web PHP en un servidor Apache 2.2 (Ubuntu Server 10.04, 8x2GHz, 12Gb RAM) usando prefork
. Cada día, Apache recibe alrededor de 100k-200k solicitudes, de estas aproximadamente 100-200 alcanza el límite de tiempo de espera (aproximadamente una de cada mil), casi todas las demás solicitudes se atienden muy por debajo del tiempo de espera.
¿Qué puedo hacer para saber por qué sucede esto? ¿O es normal que algunas partes pequeñas de todas las solicitudes se agoten?
Esto es lo que he hecho hasta ahora:
Como se puede ver, hay muy pocas solicitudes entre el límite de tiempo de espera y una solicitud más razonable. Actualmente, el límite de tiempo de espera se establece en 50 segundos, anteriormente se estableció en 300 y seguía siendo la misma situación con algunos tiempos de espera y luego una gran brecha con las otras solicitudes.
Todas las solicitudes que exceden el tiempo de espera son AJAX
solicitudes, pero la gran mayoría de ellas lo son, por lo que quizás sea más una coincidencia. El código de retorno de Apache es 200
, pero el límite de tiempo de espera se alcanza claramente. Son de una amplia gama de IP diferentes.
He examinado las solicitudes que expiran y no hay nada de especial en ellas, si hago las mismas solicitudes que reciben en mucho menos de un segundo.
He tratado de ver los diferentes recursos para ver si puedo encontrar la causa, pero no tuve suerte. Siempre hay mucha memoria libre (el mínimo es de aproximadamente 3 GB gratis), la carga a veces llega a 1.4 y la utilización de la CPU al 40%, pero muchos de los tiempos de espera se producen cuando la carga y la utilización de la CPU son bajas. La escritura / lectura en disco es bastante constante durante el día. No hay entradas en el registro de consultas lentas de MySQL (configurado para registrar cualquier cosa por encima de 1 segundo), y ninguna solicitud utiliza tantas escrituras / lecturas de bases de datos.
El azul es la utilización de la CPU, que alcanza un pico del 40%, el marrón es la carga con un pico en 1.4. Entonces podemos ver que tenemos tiempos de espera incluso con una baja utilización / carga de CPU (los picos de diez segundos corresponden bien a la utilización de la CPU, pero ese es otro problema, tengo mayores esperanzas de descubrir qué podría estar causando esos).
No hay errores en el registro de errores de Apache y no lo he visto llegar a más de 200 procesos activos de Apache.
Configuración del servidor:
Timeout 50
KeepAlive On
MaxKeepAliveRequests 100
KeepAliveTimeout 2
<IfModule mpm_prefork_module>
ServerLimit 350
StartServers 20
MinSpareServers 75
MaxSpareServers 150
MaxClients 320
MaxRequestsPerChild 5000
</IfModule>
Actualizar:
Actualicé a Ubuntu 12.04.1, por si acaso, sin cambios. Agregué mod_reqtimeout con la configuración:
RequestReadTimeout header=20-40,minrate=500
RequestReadTimeout body=10,minrate=500
Ahora, casi todos los tiempos de espera se producen a los 10 segundos, uno o dos a los 20 segundos. ¿Supongo que eso significa que la mayoría de las veces es problemático recibir el cuerpo de la solicitud? El cuerpo de la solicitud nunca debe ser mayor que unos pocos cientos de bytes. He monitoreado el tráfico de red por 1 segundo y nunca supera los 1Mbit / sy no veo ningún rxerrs o rxdorps, teniendo en cuenta que el servidor está en una línea de 1Gbit / s no suena como el HopelessN00b publicó sobre. ¿Podría ser solo un caso de algunas malas conexiones de usuario?
Para los picos cada hora (parecen desplazarse un poco, en los gráficos de arriba están encendidos 33 minutos después de la hora, ahora están en 12 minutos), he intentado ver si hay algo corriendo periódicamente ( crons, etc.) pero no encontré nada. La recolección de basura de PHP se ejecuta dos veces cada hora, pero no en el momento de los picos, todavía he intentado deshabilitarla, pero no hace ninguna diferencia.
He usado dstat con --top-cpu y top para ver los procesos en el momento de los picos y todo lo que aparece es apache trabajando duro durante unos segundos, pero ningún otro proceso está usando una CPU significativa.
He hecho un gráfico ampliado de los picos:
Para mí, parece que Apache se detiene durante unos segundos y luego trabaja duro para procesar las solicitudes que llegaron durante el alto. ¿Qué podría causar tal detención, o lo estoy malinterpretando?
fuente
Respuestas:
Lo primero que noto, al mirar su primer gráfico, parece que hay una desaceleración por hora (que ocurre aproximadamente 40 minutos después de la hora) que puede estar contribuyendo al problema. Debe echar un vistazo a los programadores de tareas en el sistema operativo / base de datos.
Según los datos que ha proporcionado, mi próximo paso sería analizar la frecuencia de los tiempos de respuesta (número de respuestas en el eje Y frente a la duración en X), pero solo incluir las URL que muestran el tiempo de espera (o preferiblemente una URL a la vez ) En un sistema típico, esto debería seguir una distribución normal o de Poisson (las solicitudes que están agotando el tiempo pueden ser simplemente parte de la cola), en cuyo caso debe concentrar sus esfuerzos en la sintonización general. OTOH si la distribución es bimodal, entonces debe buscar contención en algún lugar de su código.
fuente
Tengo otro pensamiento sobre esto, basado en el hecho de que recibe una gran cantidad de solicitudes por día, y parece tener tiempos de espera solo durante las horas pico (de las imágenes que publicó).
Hay una publicación en el blog Server Fault,
Per Second Measurements Don't Cut It
... ¿es posible que algunas de estas solicitudes se encuentren con el mismo problema que el equipo de ServerFault?fuente