2010-11-19 5 views
9

Tengo una situación extraña en un servidor de producción. La conexión para asp.net se pone en cola, pero la CPU solo está al 40%. Además, la base de datos funciona bien con un 30% de CPU.Asp.net aplicación lenta pero la CPU está al 40% máximo

Un poco más de la historia conforme a lo solicitado en los comentarios:

  • En las horas pico los sitios recibe alrededor de 20.000 visitantes por hora.
  • El sitio es una aplicación de formularios web ASP.NET con una gran cantidad de AJAX/Posts
  • El sitio utiliza una gran cantidad de contenido generado por usuarios
  • Medimos el rendimiento del sitio con un testpage que no golpeó la base de datos y los servicios web utilizados por el sitio. Esta página se sirve dentro de un segundo con carga normal. Donde se define la aplicación como lenta cuando la solicitud demora más de 4 segundos.
  • De las mediciones podemos ver que el tiempo de conexión es rápido, pero el tiempo de procesamiento es grande.
  • No podemos precisar la slowresponse la una única solicitud, el sitio funciona muy bien durante las horas normales, pero se pone lento durante las horas pico
  • ocurrido un problema que el sitio estaba obligado CPU (aka funcionando al 100%), se arreglado que
  • También tuvimos problemas con las excepciones al reiniciar el dominio de la aplicación, arreglamos que haga
  • Durante las horas punta eche un vistazo a los contadores de rendimiento asp.net. Podemos ver el comportamiento de que tenemos 600 conexiones actuales con 500 conexiones en cola.
  • En las horas punta de la CPU es de alrededor de 40% (lo que me hace el pienso que no es por CPU)
  • la memoria física es de alrededor de 60% utilizado
  • En las horas punta del DatabaseServer CPU es de alrededor de 30% (que me hace pensar que no está vinculado a la base de datos)

Mi conclusión es que algo más está impidiendo que el servidor maneje las solicitudes más rápido. Posibles sospechosos

  • interbloqueos (syncblk sólo da una cerradura!)
  • /S de disco (comprobado mediante sysinternals procesexplorer: 3.5 MB/s)
  • La recolección de basura (10 ~ 15% durante los picos)
  • E/S de red (tiempo de conexión aún bajo)

Para saber qué está haciendo el proceso creé en minivolcados.

Logré crear dos MemoryDumps con 20 segundos de diferencia. Esta es la salida de la primera:

!threadpool 
CPU utilization 6% 
Worker Thread: Total: 95 Running: 72 Idle: 23 MaxLimit: 200 MinLimit: 100 
Work Request in Queue: 1 
-------------------------------------- 
Number of Timers: 64 

y la salida de la segunda:

!threadpool 
CPU utilization 9% 
Worker Thread: Total: 111 Running: 111 Idle: 0 MaxLimit: 200 MinLimit: 100 
Work Request in Queue: 1589 

Como se puede ver hay una gran cantidad de Solicitud de cola.

Pregunta 1: lo que significa que hay 1589 solicitudes en la cola. ¿Significa que algo está bloqueando?!

La lista de subprocesos contiene en su mayoría estas entradas: función desconocida: 6a2aa293 Contexto: 01cd1558 AsyncTimerCallbackCompletion TimerInfo @ 023a2cb0

Si os en profundidad con el AsyncTimerCallbackCompletion

!dumpheap -type TimerCallback 

Entonces miro el objetos en el TimerCallback y la mayoría de ellos son de tipos:

System.Web.SessionState.SessionStateModule 
System.Web.Caching.CacheCommon 

Pregunta 2: ¿Tiene algún sentido que esos Objetos tengan un temporizador, y tanto? Debería prevenir esto ¿Y cómo?

Pregunta principal ¿Echo de menos algún problema obvio por el que estoy haciendo colas y no estoy maximizando la CPU?


Tuve éxito en hacer un crashdump durante un pico. Analizando con debugdiag me dio esta advertencia:

Detected possible blocking or leaked critical section at webengine!g_AppDomainLock owned by thread 65 in Hang Dump.dmp 
Impact of this lock 
25.00% of threads blocked 
(Threads 11 20 29 30 31 32 33 39 40 41 42 74 75 76 77 78 79 80 81 82 83) 

The following functions are trying to enter this critical section 
webengine!GetAppDomain+c9 

The following module(s) are involved with this critical section 
\\?\C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\webengine.dll from Microsoft Corporation 

Una búsqueda rápida en Google no me da ningún resultado. ¿Alguien tiene una pista?

+0

¿Has probado y medido la velocidad de Firebug? ver qué parte carga más tiempo ... luego comenzar desde allí. – Arief

+1

Esto es extremadamente difícil de diagnosticar usando la información irregular que proporcionó. ¿Hay alguna razón por la que comenzaste mirando los vertederos? ¿Tu aplicación ASP.NET está fallando? Si es así, ¿por qué clasifica esto como un problema de rendimiento? –

Respuesta

4

El proceso de trabajo que maneja la cola fue el verdadero motivo de ruptura. Probablemente conectado con el sitio web que llama a los servicios web en el mismo host. Creando así un tipo de punto muerto.

he cambiado el machine.config a al siguiente:

<processModel 
     autoConfig="false" 
     maxWorkerThreads="100" 
     maxIoThreads="100" 
     minWorkerThreads="50" 
     minIoThreads="50" /> 

Estándar esta processmodel se establece en autoConfig = "true"

Con la nueva configuración del servidor web es el manejo de las solicitudes suficientemente rápido como para no ponte en cola

+0

alguna idea de cómo 'autoConfig = true' decide qué valores poner donde? ¿Estoy usando específicamente servicios web azules? – Zapnologica

2

Demasiadas solicitudes en cola ASP.NET destruirán el rendimiento. Hay un número muy limitado de hilos de solicitud.

Intente liberar esos subprocesos procesando partes lentas de sus páginas de forma asincrónica o haciendo cualquier otra cosa que pueda para reducir los tiempos de ejecución de la página.

+1

Sí, entiendo. Sin embargo, no entiendo por qué no está procesando las solicitudes más rápido ya que la CPU no está al máximo. – wasigh

+0

Mi dinero está en la red/bases de datos de ida y vuelta. ¿Puedes poner el código del cronómetro alrededor de cada una de estas solicitudes? – realworldcoder

+0

Las solicitudes no se procesarán porque se está acabando el hilo de ASP.NET. ASP.NET no está inyectando nuevos subprocesos en el grupo a una velocidad lo suficientemente rápida como para que usted maximice la CPU. Asynchrony ayuda porque le permitirá reutilizar subprocesos existentes mientras espera a que finalicen sus llamadas de servicio web back-end. –

3

Estoy con realworldcoder: IIS funciona haciendo que los procesos de trabajo manejen las solicitudes entrantes. Si las solicitudes se acumulan, como está sucediendo, entonces el rendimiento se zambulle.

Hay varias cosas posibles que hacer/verificar.

  1. Encienda el Monitor de actividad en el servidor SQL. Desea ver qué consultas tardan más tiempo y, según los resultados, realizar cambios para reducir el tiempo de ejecución. Las consultas largas pueden hacer que el subproceso bajo el que se ejecuta la página bloquee, reduciendo la cantidad de conexiones que puede admitir.

  2. Mire el número de consultas, y el tiempo que tardan en ejecutarse, para estas llamadas de página/ajax. He visto páginas con docenas de consultas innecesarias que se ejecutan para una llamada Ajax simplemente porque .Net ejecuta todo el ciclo de la página, incluso cuando solo se debe ejecutar un método en particular. Puede dividir esas llamadas en páginas normales de manejadores web (.ashx) para que pueda controlar mejor exactamente lo que sucede.

  3. Considere aumentar el número de procesos de trabajo que IIS tiene que gestionar las solicitudes entrantes. El valor predeterminado para un grupo de aplicaciones nuevo es 1 proceso con 20 threads. Esto suele ser suficiente para manejar toneladas de solicitudes; sin embargo, si las solicitudes se bloquean debido a la espera en el servidor de bases de datos o algún otro recurso, puede causar que la tubería se acumule. Tenga en cuenta que esto puede tener un impacto positivo o negativo en el rendimiento y el funcionamiento regular de su aplicación. Así que investigue un poco y luego pruebe, pruebe y pruebe.

  4. Considere reducir o eliminar el uso de la sesión.De cualquier manera, fíjate en el uso de la memoria, posiblemente agregue más memoria RAM a tu servidor web. Los datos de sesión se serializan y deserializan para cada carga de página (incluidas las llamadas ajax) independientemente de si los datos se utilizan o no. Dependiendo de lo que esté almacenando en sesión, puede tener un impacto negativo serio en su sitio. Si no lo está utilizando, asegúrese de que esté completamente desactivado en su web.config. Tenga en cuenta que estos problemas solo empeorarán si almacena la sesión fuera del servidor web, ya que luego se ve obligado a la velocidad de la red cuando una página la recupera y almacena.

  5. Mire los contadores de rendimiento de sitios alrededor de la compilación JIT (Just-In-Time). Esto debería ser casi inexistente. He visto sitios arrodillados por grandes cantidades de JIT. Una vez que esas páginas fueron recodificadas para eliminarlo, los sitios comenzaron a volar otra vez.

  6. Mire diferentes estrategias de almacenamiento en caché (no considero que la sesión sea una solución real de almacenamiento en caché). Quizás haya cosas que solicite constantemente que realmente no necesite sacar constantemente del servidor de bases de datos. Un amigo mío tiene un sitio donde almacenan en caché páginas web enteras como archivos físicos para contenido dinámico, incluidos sus grupos de discusión. Esto ha aumentado radicalmente su rendimiento; pero es un cambio arquitectónico importante.

Lo anterior son solo un par de cosas a la vista. Básicamente necesita profundizar en los detalles para descubrir exactamente qué está pasando y la mayoría de los contadores de rendimiento regulares no le darán esa claridad.

0

¿Alguien pudo confirmar que esto funcionó para ellos? Encontré esa respuesta en la Web y no hay confirmación de que la respuesta publicada haya solucionado este problema. Habiendo dicho eso, realmente no le doy credibilidad ya que la respuesta la proporciona el afiche de la pregunta.

que tiene el mismo problema hace poco:

Detectado posible bloqueo o filtrado sección crítica en WebEngine g_AppDomainLock propiedad de hilo 16 en w3wp.exe__DefaultAppPool__PID__3920__Date__04_26_2011__Time_10_40_42AM__109__IIS_COM + Cuelgue Dump.dmp impacto de esta cerradura

4.17% de los hilos bloqueados (Hilos 17) Las siguientes funciones están intentando ingresar a esta sección crítica del motor web. GetAppDoma en + c9 Los siguientes módulos están relacionados con esta sección crítica \? \ c: \ WINDOWS \ microsoft.net \ framework \ v2.0.50727 \ webengine.DLL desde Microsoft Corporation

Ésta es la recomendación publicado por Microsoft para resolver otros problemas: se identificaron

Los siguientes proveedores de seguimiento basado en la raíz análisis de la causa Microsoft Corporation favor seguimiento con el vendedores identificados arriba. Considere el siguiente enfoque para determinar la causa raíz de este problema crítico sección :

  1. Habilitar 'Lock comprobaciones' en el comprobador de aplicaciones A. Descargar Comprobador de aplicación de la siguiente URL: http://www.microsoft.com/downloads/en/details.aspx?FamilyID=c4a25ab9-649d-4a1b-b4a7-c9d8b095df18&displaylang=en B. Activar 'Lock cheques' para este proceso mediante la ejecución del siguiente comando:

    Appverif.exe -enable locks -for w3wp.exe C. Consulte el siguiente documento para obtener más información sobre el comprobador de aplicaciones: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnappcom/html/appverifier.asp?frame=true

  2. Use una regla de bloqueo DebugDiag para supervisar la aplicación de excepciones

1

Sé que esto es un hilo viejo, pero es una de las primeras Google golpea para las personas con mal rendimiento del sitio ASP.NET. Entonces lanzaré algunas recomendaciones:

1) La programación asincrónica resolverá la causa raíz. Mientras llama a un servicio web para que haga su lógica comercial real, esos hilos de solicitud están esperando allí la respuesta. Podrían usarse en su lugar para dar servicio a otra solicitud entrante. Esto reducirá drásticamente la duración de la cola si no la elimina por completo. La programación asincrónica se trata de la escalabilidad, no del rendimiento de solicitud individual. Esto se logra bastante fácil en .NET 4.5 con el patrón Async/Await. ASP.NET inyecta hilos a una velocidad de 2 por minuto, por lo tanto, a menos que reutilice los hilos existentes, se agotará rápidamente con la carga del sitio que está recibiendo. Además, girar más hilos es un pequeño golpe de rendimiento; toma más RAM y tiempo para asignar esa RAM. Solo aumentar el tamaño del grupo de subprocesos en machine.config no solucionará el problema subyacente. A menos que agregue más CPU, agregar más subprocesos no será de gran ayuda, ya que sigue siendo una mala asignación de recursos y también puede cambiar el contexto a la muerte por tener demasiados hilos y muy poca CPU.

2) From a popular article on threading in IIS 7.5: Si su aplicación ASP.NET está utilizando servicios web (WFC o ASMX) o System.Net para comunicarse con un servidor a través de HTTP, puede necesitar aumentar connectionManagement/maxconnection. Para las aplicaciones ASP.NET, esto está limitado a 12 * #CPU por la función autoconfig. Esto significa que en un quad-proc, puede tener como máximo 12 * 4 = 48 conexiones concurrentes a un punto final de IP. Como esto está relacionado con la configuración automática, la forma más fácil de aumentar la conexión máxima en una aplicación ASP.NET es establecer System.Net.ServicePointManager.DefaultConnectionLimit programáticamente, desde Application_Start, por ejemplo. Establezca el valor en la cantidad de conexiones simultáneas de System.Net que espera que use su aplicación. Lo configuré en Int32.MaxValue y no tuve ningún efecto secundario, por lo que podría intentarlo: este es el valor predeterminado utilizado en la pila HTTP nativa, WinHTTP. Si no puede establecer System.Net.ServicePointManager.DefaultConnectionLimit programáticamente, deberá deshabilitar la configuración automática, pero eso significa que también debe establecer maxWorkerThreads y maxIoThreads. No necesitará establecer minFreeThreads o minLocalRequestFreeThreads si no está utilizando el modo clásico/ISAPI.

3) Debería mirar realmente el equilibrio de carga si obtiene 20k visitantes únicos por hora. Si cada usuario hiciera entre 10 y 20 solicitudes de AJAX por hora, estarás hablando fácilmente de 1 millón o más de llamadas de servicio web a tu back-end. Lanzar otro servidor reduciría la carga en el servidor primario. Combinando esto con async/await, te encuentras en una buena situación donde puedes lanzar hardware fácilmente al problema (escalado). Aquí hay múltiples beneficios, como redundancia de hardware, geolocalización y también rendimiento. Si está usando un proveedor de la nube como AWS o RackSpace, hacer girar otra máquina virtual con su aplicación es lo suficientemente fácil como para hacerlo desde su teléfono móvil. La computación en la nube es muy barata hoy en día incluso para tener una longitud de cola en absoluto. Podría hacer esto para proporcionar los beneficios de rendimiento incluso antes de pasar a un modelo de programación asíncrona.

4) Ampliación: agregar más hardware a su (s) servidor (es) de ayuda porque proporciona una mejor estabilidad cuando tiene hilos adicionales. Más hilos significa que necesita más CPU y RAM. E incluso después de que hayas tenido la función de sincronización/espera bajo tu cinturón, querrás ajustar esas solicitudes de servicio web si puedes. Esto podría significar agregar una capa de almacenamiento en caché o reforzar su sistema de base de datos. NO quiere maximizar la CPU en ese único servidor. Una vez que la CPU alcanza el 80%, ASP.NET dejará de inyectar más subprocesos en el sistema. No importa si el proceso de trabajo está al 0%, si la utilización total de la CPU del sistema según lo reportado por el Administrador de tareas alcanza el 80%, entonces la inyección de subprocesos se detiene y las solicitudes comienzan a cola. Las cosas extrañas con la recolección de basura también ocurren cuando detecta una alta carga de CPU en el servidor.

+0

Disfruté sus dos primeros puntos, sin embargo, no creo que el hardware de escalado sea una solución cuando el OP indicaba que la máquina actual está inactiva. Me imagino que uno solo haría eso una vez, han hecho las optimizaciones sugeridas y la máquina tiene más del 80% de los recursos. – Zapnologica

+0

@Zapnologica OP tiene problemas de bloqueo, lo que hace que parezca que la máquina está inactiva, pero está obteniendo una escabilidad general deficiente. Las optimizaciones que hizo fueron para aumentar el conteo de subprocesos, que no es la solución correcta si tiene una gran carga de trabajo de E/S (bases de datos de llamadas u otros servicios de red). Más hilos tendrán una mayor utilización de CPU (giros, cambio de contexto). Menos subprocesos pero trabajando en una moda de multiplexación de E/S solapada tendrán una mejor escalabilidad general. La ampliación del hardware es una buena solución provisional si se trata de cargas de trabajo súbitas y necesita una solución temporal. –

Cuestiones relacionadas