Visualización de datos de Application Insights Profiler para .NET

Imagine que está ejecutando una prueba de rendimiento web. Necesitará realizar seguimientos para saber si la aplicación web funciona correctamente en condiciones de carga. En este artículo, hará lo siguiente:

  • Genere tráfico a la aplicación web iniciando una prueba de rendimiento web o iniciando una sesión a petición de Profiler.
  • Vea los seguimientos de Profiler después de la prueba de carga o la sesión de Profiler.
  • Obtenga información sobre cómo leer los datos de rendimiento de Profiler y la pila de llamadas.

Genere tráfico al servicio Azure

Para que el Generador de perfiles de .NET cargue los seguimientos, su servicio debe estar controlando activamente las solicitudes.

Si acaba de habilitar Profiler para .NET, ejecute una prueba de carga corta con Azure Load Testing.

Si la servicio Azure ya tiene tráfico entrante o si solo desea generar manualmente el tráfico, omita la prueba de carga e inicie una Sesión a petición de Profiler:

  1. En la página de información general de Application Insights de su servicio Azure, seleccione Rendimiento en el menú izquierdo.

  2. En el panel Rendimiento, seleccione Profiler en el menú superior para la configuración de Profiler.

    Captura de pantalla del botón Profiler del panel Rendimiento.

  3. Una vez que se cargue la página de configuración de Profiler, seleccione Generar perfiles ahora.

    Captura de pantalla de la configuración y las características de la página de Profiler.

Visualización de seguimientos

  1. Una vez que las sesiones de Profiler terminen de ejecutarse, vuelva al panel Rendimiento.

  2. En Aumentar detalle..., seleccione Seguimientos de Profiler para ver los seguimientos.

    Captura de pantalla de la página del explorador de seguimiento.

El explorador de seguimiento muestra la siguiente información:

Filter Descripción
Árbol de perfil frente a Grafo de llamas Vea los seguimientos como un árbol o en forma de grafo.
Ruta de acceso activa Seleccione esta opción para abrir el nodo hoja más grande. En la mayoría de los casos, este nodo está cerca de un cuello de botella de rendimiento.
Dependencias del marco Seleccione esta opción para ver cada una de las dependencias del marco de seguimiento asociadas a los seguimientos.
Ocultar eventos Escriba las cadenas que se ocultarán en la vista de seguimiento. Seleccione Eventos sugeridos para obtener sugerencias.
Evento Nombre de evento o función. El árbol muestra una combinación de código y eventos que se han producido (como, por ejemplo eventos HTTP y SQL). El evento superior representa la duración total de la solicitud.
Módulo Módulo en el que se produjo el evento o la función de seguimiento.
Hora de subproceso el intervalo de tiempo entre el inicio y el final de la operación.
Escala de tiempo el momento en que se ejecutó la función o el evento con relación a otras funciones.

Cómo leer datos de rendimiento

El Generador de perfiles de .NET usa una combinación de métodos de muestreo e instrumentación para analizar el rendimiento de su aplicación. Mientras realiza la recopilación detallada, el Generador de perfiles de .NET:

  • Muestra el puntero de instrucción de cada CPU de la máquina cada milisegundo.
    • Cada muestra captura la pila de llamadas completa del subproceso, dando información detallada en los niveles de abstracción tanto altos como bajos.
  • Recopila eventos para realizar un seguimiento de la correlación de actividad y la causalidad, entre los que se incluyen:
    • Eventos de cambio de contexto
    • Eventos de biblioteca de procesamiento paralelo basado en tareas (TPL)
    • Eventos de grupo de subprocesos

La pila de llamadas que se muestra en la vista de escala de tiempo es el resultado del muestreo y la instrumentación. Como cada muestra captura la pila de llamadas completa del subproceso, incluye código de Microsoft .NET Framework y de cualquier otro marco al que haga referencia.

Asignación de objetos (clr!JIT_New o clr!JIT_Newarr1)

clr!JIT_New y clr!JIT_Newarr1 son funciones auxiliares de .NET Framework que asignan memoria desde un montón administrado.

  • clr!JIT_New se invoca cuando se asigna un objeto.
  • clr!JIT_Newarr1 se invoca cuando se asigna una matriz de objetos.

Estas dos funciones suelen funcionar rápidamente. Si clr!JIT_New o clr!JIT_Newarr1 se prolongan en la escala de tiempo, significa que el código podría estar asignando muchos objetos y consumiendo una importante cantidad de memoria.

Código de carga (clr!ThePreStub)

clr!ThePreStub es una función auxiliar en .NET Framework que prepara el código para la ejecución inicial, que normalmente incluye la compilación Just-In-Time (JIT). Para cada método de C#, se debe invocar clr!ThePreStub una vez como máximo durante un proceso.

Si clr!ThePreStub tarda más tiempo para una solicitud, significa que la solicitud es la primera que ejecuta ese método. El runtime de .NET Framework tarda mucho tiempo en cargar el primer método. Tenga en cuenta lo siguiente:

  • Usar un proceso de preparación que ejecute esa parte del código antes de que los usuarios accedan a él.
  • Ejecutar el generador de imágenes nativas (ngen.exe) en los ensamblados.

Contención de bloqueo (clr!JITutil_MonContention o clr!JITutil_MonEnterWorker)

clr!JITutil_MonContention o clr!JITutil_MonEnterWorker indican que el subproceso actual está a la espera de que se libere un bloqueo. Este texto se muestra a menudo cuando:

  • Se ejecuta una instrucción LOCK de C#.
  • Se invoca el método Monitor.Enter.
  • Se invoca un método con el atributo MethodImplOptions.Synchronized.

La contención de bloqueo se produce normalmente cuando un subproceso A adquiere un bloqueo y un subproceso B intenta adquirir el mismo bloqueo antes de que el subproceso A lo libere.

Código de carga ([COLD])

Si el runtime de .NET Framework ejecuta código no optimizado por primera vez, el nombre del método contendrá [COLD]:

mscorlib.ni![COLD]System.Reflection.CustomAttribute.IsDefined

Para cada método, debe presentarse una vez durante el proceso, como máximo.

Si el código de carga tarda una cantidad de tiempo considerable para una solicitud, significa que es la ejecución inicial de la solicitud de la parte no optimizada del método. Considere la posibilidad de usar un proceso de preparación que ejecute esa parte del código antes de que los usuarios accedan e él.

Enviar solicitud HTTP

Métodos como HttpClient.Send indican que el código está esperando a que finalice una solicitud HTTP.

Operación de base de datos

Métodos como SqlCommand.Execute indican que el código está a la espera de que finalice una operación de base de datos.

Espera (AWAIT_TIME)

AWAIT_TIME indica que el código está a la espera de que finalice otra tarea. Este retraso se produce con la instrucción AWAIT de C#. Cuando el código ejecuta una instrucción AWAIT de C#:

  • El subproceso desenreda y devuelve el control al grupo de subprocesos.
  • No hay ningún subproceso bloqueado esperando a que finalice AWAIT.

Pero, lógicamente, el subproceso que ejecutó AWAIT se "bloquea" en espera de que se complete la operación. La instrucción AWAIT_TIME indica el tiempo de bloqueo a la espera de que finalice la tarea.

Si AWAIT_TIME aparece en el código del marco en lugar de en su código, el Generador de perfiles de .NET podría estar mostrando:

  • El código de marco usado para ejecutar AWAIT.
  • El código usado para grabar telemetría sobre AWAIT.

Puede desactivar la casilla Dependencias del marco en la parte superior de la página para mostrar solo el código y facilitar la visualización de dónde se origina AWAIT.

Tiempo de bloqueo

BLOCKED_TIME indica que el código está a la espera de que otro recurso esté disponible. Por ejemplo, puede estar esperando lo siguiente:

  • Un objeto de sincronización
  • La disponibilidad de un subproceso
  • La finalización de una solicitud

Async no administrada

Para que se pueda realizar un seguimiento de las llamadas asincrónicas entre subprocesos, .NET Framework emite eventos ETW y pasa identificadores de actividad entre subprocesos. Dado que el código no administrado (nativo) y algunos estilos más antiguos de código asincrónico carecen de estos eventos e id. de actividad, el Generador de perfiles de .NET no puede supervisar la conversación y las funciones que se ejecutan en el subproceso. Este elemento se etiqueta como Asincrónico no administrado en la pila de llamadas. Descargue el archivo ETW para usar PerfView para más información.

Tiempo de CPU

La CPU está ocupada ejecutando las instrucciones.

Tiempo de disco

La aplicación está ejecutando operaciones de disco.

Tiempo de red

La aplicación está ejecutando operaciones de red.

Columna Cuándo

La columna Cuándo es una visualización de la variedad de las muestras inclusivas recopiladas para un nodo a lo largo del tiempo. El intervalo total de la solicitud se divide en 32 depósitos, donde se acumulan las muestras inclusivas de nodos. Cada depósito se representa con una barra. El alto de la barra representa un valor escalado. Para los nodos siguientes, la barra representa el consumo de uno de los recursos durante el depósito:

  • Nodos marcados CPU_TIME o BLOCKED_TIME.
  • Nodos con una relación obvia para consumir un recurso (por ejemplo, una CPU, un disco o un subproceso).

Con estas métricas, puede conseguir un valor de más del 100 % si consume varios recursos. Por ejemplo, si usa dos CPU a lo largo de un intervalo de promedio, consigue el 200 %.

Pasos siguientes

Obtenga información sobre...