2008-10-06 16 views
10

Ejecutamos un sitio de tamaño mediano que obtiene unos pocos cientos de miles de vistas de página por día. Hasta el último fin de semana corrimos con una carga generalmente inferior a 0.2 en una máquina virtual. El sistema operativo es Ubuntu.Apache usa una CPU excesiva

Al implementar la última versión de nuestra aplicación, también hicimos un apt-get dist-upgrade antes de implementarlo. Después de desplegarnos, notamos que la carga en la CPU había aumentado drásticamente (a veces llegando a 10 y deteniéndose para responder a las solicitudes de página).

Intentamos eliminar un minuto completo de los datos de perfilado de Xdebug desde PHP, pero al examinarlo se revelaron solo algunas partes algo lentas, pero nada que explicara el gran salto.

Ahora estamos bastante seguros de que nada en la nueva versión de nuestro sitio web está desencadenando el problema, pero no tenemos manera de estar seguros. Hemos revertido muchos de los cambios, pero el problema aún persiste.

Cuando miramos los procesos, vemos que los procesos de Apache solo utilizan bastante CPU durante un período de tiempo más largo que estrictamente necesario. Sin embargo, cuando se utiliza strace en el proceso afectado, nunca vemos nada, pero

accept(3, 

y se cuelga por un tiempo antes de recibir una nueva conexión, por lo que no podemos ver realmente lo que está causando el problema.

La pila es PHP 5, Apache 2 (prefork), MySQL 5.1. La mayoría de las cosas pasan por Memcached. Hemos probado APC y eAccelerator.

Entonces, ¿cuál debería ser nuestro siguiente paso? ¿Hay algún método de creación de perfiles que ignoramos/desconocemos?

+0

¿De qué versiones a qué versiones actualizaste el sistema? Me refiero a a) PHP, b) Apache yc) memcached. – Georgi

+0

No tengo un registro de eso, desafortunadamente. Por lo que sé, no hay ningún registro apt-get/aptitude. –

Respuesta

11

La respuesta terminó siendo no relacionada con Apache. Como mencioné, estábamos en una máquina virtual. Nuestras sesiones de usuarios son bastante grandes (creo que 500kB por usuario activo), así que teníamos mucho disco IO. El disco estaba casi lleno, lo que significa que Ubuntu pasó mucho tiempo moviendo las cosas (o eso creemos). No había una forma sencilla de extender el disco (porque no estaba configurado correctamente para VMWare). Esto mató por completo el rendimiento, y Apache y MySQL de vez en cuando usaban 100% de CPU (durante un tiempo muy corto), y el sistema tardaría tanto en actualizar los medidores de uso de la CPU que parecían estar bloqueados allí.

Terminamos configurando una nueva máquina virtual (que también nos dio la oportunidad de documentar todo en el servidor). En la nueva máquina virtual asignamos mucho espacio en disco y movimos sesiones a la memoria (usando memcached). Nuestra carga se redujo a 0.2 en el uso fuera del pico y alrededor de 1 cerca del uso máximo (en una VM de 2 CPU). Al mover las sesiones a memcached, nos quedamos sin disco (estábamos constantemente usando aproximadamente 2MB/s de disco IO, lo cual es muy malo).

Conclusión; a veces solo tienes que empezar de nuevo ... :)

1

Tal vez estaba usando MPM de trabajador antes y ahora no?

Sé que PHP5 no funciona con Worker MPM. En mi servidor Ubuntu, PHP5 solo se puede instalar con Prefork MPM. Parece que el módulo PHP5 no es compatible con la versión multihilo de Apache.

He encontrado un enlace aquí que le mostrará cómo obtener un mejor rendimiento con mod_fcgid

Para ver qué trabajador MPM es ver here.

+0

Apache aún se está ejecutando con prefork. PHP está funcionando bien. –

+0

Sin ideas, me temo que pensé que podría haber estado utilizando php4 en su versión anterior de la aplicación y ahora que el updrade a php5 apapche se está ejecutando en modo prefork. ¿Tu versión anterior de la aplicación usaba php4? –

+0

Tal vez alrededor de un mes de edad. Hacemos actualizaciones antes de cada implementación. Sin embargo, podríamos dejar de hacer eso después de este problema ... :) –

1

Utilizaría dTrace para resolver este misterio ... si se ejecutara en Solaris o Mac ... pero como Linux no lo tiene es posible que desee probar su Systemtap, sin embargo, no puedo decir nada sobre su usabilidad ya que no lo he usado.

con Dtrace Desde aquí se puede olfatear los culpables dentro de un día, y esperaría con Systemtap sería similar

+0

Systemtap parece un poco complicado por ahora. –

0

Otra opción que yo no puedo asegurar que va a hacer ningún bien, pero es más que digno de la esfuerzo. Es leer el registro de cambios detallado de la nueva versión y revisar lo que podría haber cambiado y que podría afectarlo remotamente.

Pasar por los registros de cambios me ha salvado más de una vez. Especialmente cuando algunas opciones de configuración han cambiado y cuando algo se ha depreciado. El peor caso es que le dará algunas pistas sobre dónde buscar después

+0

Para este caso, realmente no ha ayudado. Hicimos esto inicialmente, y encontramos algunos problemas de rendimiento, pero deshacer esos cambios no resolvió el problema, desafortunadamente. –

5

Ver una llamada accept() desde su proceso Apache no es para nada inusual: es el servidor web esperando una nueva solicitud.

Antes que nada, quiere establecer cuáles son los parámetros de la carga. Algo como

vmstat 1 

le mostrará lo que su sistema está haciendo. Mire en las columnas 'swap' e 'io'. Si ve algo que no sea '0' en las columnas 'si' y 'so', su sistema se intercambiará debido a una condición de memoria baja. Considere reducir la cantidad de hijos de Apache en ejecución, o lanzar más RAM en su servidor.

Si la RAM no es un problema, mira las columnas 'cpu'. Le interesan las columnas 'nosotros' y 'sy'. Estos le muestran el porcentaje de tiempo de CPU gastado en procesos de usuario o sistema. Un número alto de 'nosotros' señala con el dedo a Apache o a sus scripts, o potencialmente algo más en el servidor.

Correr

top 

le mostrará qué procesos son los más activos.

¿Ha descartado su base de datos? La causa más común de carga inesperadamente alta que he visto en la producción Las pilas LAMP se reducen a las consultas de la base de datos. Es posible que haya implementado un nuevo código con una consulta costosa; o llegaste al punto en el que hay suficientes filas en tu conjunto de datos para que las consultas previamente baratas se vuelvan caras.

Durante los períodos de alta carga, hacen

echo "show full processlist" | mysql | grep -v Sleep 

para ver si hay o consultas de larga duración, o un gran número de la misma consulta que operan a la vez. Otras herramientas de mysql te ayudarán a optimizarlas.

Puede que le resulte útil configurar y usar mod_status para Apache, lo que le permitirá ver qué solicitud está sirviendo cada hijo de Apache y durante cuánto tiempo lo ha estado haciendo.

Finalmente, consiga una configuración de supervisión estadística a largo plazo. Algo como zabbix es sencillo de configurar y le permitirá monitorear el uso de recursos a lo largo del tiempo, de modo que si las cosas se vuelven lentas, tiene líneas de base históricas para comparar y una mejor versión de cuándo comenzaron los problemas.

+0

El problema es que Apache usa la CPU. Hay RAM más que suficiente (corrimos 512MB antes de la actualización, ahora tenemos 2GB). No hay intercambio está sucediendo. El registro de consultas lentas de MySQL no informa nada inusual. Ahora estamos viendo un aumento de carga a los 40, durante el uso intensivo. –

+0

mod_status es su mejor apuesta desde aquí. Además, para aplicar todos sus procesos de Apache, en lugar de solo el padre, intente: ps aux | grep h [t] tpd | awk '{print "-p" $ 2}' | xargs strace –

Cuestiones relacionadas