¿Cómo depurar los tiempos de espera de apache?

13

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:

Solicita tiempo de respuesta

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 AJAXsolicitudes, 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.

Solicitar tiempo de respuesta con carga del sistema / CPU

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: Tiempo de respuesta de solicitud ampliada

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?

León
fuente
1
Quería publicar con algunos gráficos sobre las solicitudes, pero mi representante es demasiado bajo.
Leon

Respuestas:

4

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.

symcbean
fuente
Gracias por su respuesta. Estoy investigando qué podría estar causando la desaceleración horaria. Mientras tanto, hice una gráfica de frecuencia de los datos que ya tengo. Esta es solo una de las URL que tiene un problema de tiempo de espera (pero las otras se ven muy similares): leela.kikora.no/apache_hist_show.png La cantidad de tiempos de espera es muy pequeña en comparación con los que toma menos de 10 segundos, pero parece como si no fuera parte de la cola. Pero, por otro lado, podría ser solo que, dado que representan cualquier cosa que hubiera tomado más de 50 segundos, se supone que debe verse así.
Leon
3

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?

Descubrimos que descartábamos paquetes con bastante frecuencia en interfaces de 1 Gbit / s a ​​velocidades de solo 10-30 MBit / s, lo que perjudica nuestro rendimiento. Esto se debe a que esa velocidad de 10-30 MBit / s es realmente el número de bits transferidos por 5 minutos convertidos a una velocidad de un segundo. Cuando profundizamos más con Wireshark y utilizamos gráficos de E / S de un milisegundo, vimos que frecuentemente explotábamos la velocidad de 1 Mbit por milisegundo de las llamadas interfaces de 1 Gbit / s.

HopelessN00b
fuente
Interesante, lo echaré un vistazo. He habilitado mod_reqtimeout y lo configuré en RequestReadTimeout header = 20-40, minrate = 500 y RequestReadTimeout body = 10, minrate = 500 y casi todos los tiempos de espera suceden en 10 segundos. Supongo que significa que el cuerpo de la solicitud tarda demasiado (el cuerpo nunca debe tener más de unos cientos de bytes como máximo), por lo que algunos de mis usuarios tienen malas conexiones o, como usted dice, hay cierta congestión en el lado de mi servidor.
Leon