Udostępnij za pośrednictwem


Wyświetlanie profilera usługi Application Insights dla danych platformy .NET

Załóżmy, że uruchamiasz internetowy test wydajnościowy. Aby dowiedzieć się, jak aplikacja internetowa jest uruchomiona pod obciążeniem, potrzebne są ślady. W tym artykule wykonasz następujące elementy:

  • Wygeneruj ruch do aplikacji internetowej, uruchamiając internetowy test wydajnościowy lub uruchamiając sesję profilera na żądanie.
  • Wyświetl ślady profilera po sesji testu obciążeniowego lub profilera.
  • Dowiedz się, jak odczytywać dane wydajności i stos wywołań profilera.

Generowanie ruchu do usługi platformy Azure

Aby program .NET Profiler mógł przekazywać ślady, usługa musi aktywnie obsługiwać żądania.

Jeśli nowo włączono narzędzie Profiler dla platformy .NET, uruchom krótki test obciążeniowy przy użyciu testowania obciążenia platformy Azure.

Jeśli usługa platformy Azure ma już ruch przychodzący lub chcesz ręcznie wygenerować ruch, pomiń test obciążeniowy i uruchom sesję profilera na żądanie:

  1. Na stronie przeglądu usługi Application Insights dla usługi Azure wybierz pozycję Wydajność z menu po lewej stronie.

  2. W okienku Wydajność wybierz pozycję Profiler z górnego menu w obszarze Ustawienia profilera.

    Zrzut ekranu przedstawiający przycisk Profiler w okienku Wydajność.

  3. Po załadowaniu strony Ustawienia profilera wybierz pozycję Profil teraz.

    Zrzut ekranu przedstawiający funkcje i ustawienia strony profilera.

Wyświetlanie śladów

  1. Po zakończeniu działania sesji profilera wróć do okienka Wydajność .

  2. W obszarze Przechodzenie do szczegółów wybierz pozycję Ślady profilera, aby wyświetlić ślady.

    Zrzut ekranu przedstawiający stronę eksploratora śledzenia.

W Eksploratorze śledzenia są wyświetlane następujące informacje:

Filtr opis
Drzewo profilów v. Wykres płomienia Wyświetl ślady jako drzewo lub w postaci grafu.
Ścieżka gorąca Wybierz, aby otworzyć największy węzeł liścia. W większości przypadków ten węzeł znajduje się w pobliżu wąskiego gardła wydajności.
Zależności struktury Wybierz, aby wyświetlić każdą ze śledzonych zależności struktury skojarzonych ze śladami.
Ukryj zdarzenia Wpisz ciągi, aby ukryć się w widoku śledzenia. Wybierz pozycję Sugerowane zdarzenia , aby uzyskać sugestie.
Zdarzenie Nazwa zdarzenia lub funkcji. W drzewie jest wyświetlana kombinacja kodu i zdarzeń, które wystąpiły, takich jak zdarzenia SQL i HTTP. Najważniejsze zdarzenie reprezentuje ogólny czas trwania żądania.
Moduł Moduł, w którym wystąpiło śledzone zdarzenie lub funkcja.
Czas wątku Przedział czasu między rozpoczęciem operacji a końcem operacji.
Oś czasu Czas działania funkcji lub zdarzenia w odniesieniu do innych funkcji.

Jak odczytywać dane wydajności

Program .NET Profiler używa kombinacji metod próbkowania i instrumentacji do analizowania wydajności aplikacji. Podczas wykonywania szczegółowej kolekcji profiler platformy .NET:

  • Przykładowy wskaźnik instrukcji dla każdego procesora CPU każdego milisekundy.
    • Każdy przykład przechwytuje pełny stos wywołań wątku, podając szczegółowe informacje zarówno na wysokim, jak i niskim poziomie abstrakcji.
  • Zbiera zdarzenia w celu śledzenia korelacji i przyczynowości działań, w tym:
    • Zdarzenia przełączania kontekstu
    • Zdarzenia biblioteki równoległej zadań (TPL)
    • Zdarzenia puli wątków

Stos wywołań wyświetlany w widoku osi czasu jest wynikiem próbkowania i instrumentacji. Ponieważ każdy przykład przechwytuje pełny stos wywołań wątku, zawiera kod z programu Microsoft .NET Framework oraz wszystkie inne struktury, do których się odwołujesz.

Alokacja obiektów (clr! JIT_New lub clr! JIT_Newarr1)

Clr! JIT_New i clr! JIT_Newarr1 to funkcje pomocnicze w programie .NET Framework, które przydzielają pamięć z zarządzanego sterta.

  • Clr! JIT_New jest wywoływany po przydzieleniu obiektu.
  • Clr! JIT_Newarr1 jest wywoływany po przydzieleniu tablicy obiektów.

Te dwie funkcje zwykle działają szybko. Jeśli clr! JIT_New lub clr! JIT_Newarr1 poświęcać czas na osi czasu, kod może przydzielać wiele obiektów i zużywać znaczną ilość pamięci.

Ładowanie kodu (clr! ThePreStub)

Clr! ThePreStub to funkcja pomocnika w programie .NET Framework, która przygotowuje kod do początkowego wykonywania, który zwykle obejmuje kompilację just in time (JIT). Dla każdej metody języka C# clr! ElementPreStub powinien być wywoływany co najwyżej raz podczas procesu.

Jeśli clr! Parametr ThePreStub zajmuje dodatkowy czas dla żądania— jest to pierwsze żądanie do wykonania tej metody. Ładowanie pierwszej metody w środowisku uruchomieniowym programu .NET Framework zajmuje znaczną ilość czasu. Rozważ następujące kwestie:

  • Przy użyciu procesu rozgrzewania, który wykonuje ten fragment kodu przed uzyskaniem dostępu do niego przez użytkowników.
  • Uruchamianie generatora obrazów natywnych (ngen.exe) w zestawach.

Blokowanie rywalizacji (clr! JITutil_MonContention lub clr! JITutil_MonEnterWorker)

Clr! JITutil_MonContention lub clr! JITutil_MonEnterWorker wskazują, że bieżący wątek czeka na zwolnienie blokady. Ten tekst jest często wyświetlany w następujących sytuacjach:

  • Wykonywanie instrukcji LOCK w języku C#,
  • Wywoływanie metody Monitor.Enter lub
  • Wywołaj metodę za pomocą atrybutu MethodImplOptions.Syncd .

Rywalizacja o blokadę zwykle występuje, gdy wątek A uzyskuje blokadę i wątek B próbuje uzyskać tę samą blokadę przed wydaniem wątku A .

Ładowanie kodu ([COLD])

Jeśli środowisko uruchomieniowe programu .NET Framework wykonuje niezoptymalizowany kod po raz pierwszy, nazwa metody będzie zawierać wartość [COLD]:

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

Dla każdej metody powinna być wyświetlana raz w trakcie procesu, co najwyżej.

Jeśli ładowanie kodu zajmuje znaczną ilość czasu dla żądania, jest to zainicjowanie wykonania niezoptymalizowanej części metody przez żądanie. Rozważ użycie procesu rozgrzewania, który wykonuje ten fragment kodu przed uzyskaniem dostępu do niego przez użytkowników.

Wysyłanie żądania HTTP

Metody, takie jak HttpClient.Send , wskazują, że kod oczekuje na ukończenie żądania HTTP.

Operacja bazy danych

Metody, takie jak SqlCommand.Execute , wskazują, że kod oczekuje na zakończenie operacji bazy danych.

Oczekiwanie (AWAIT_TIME)

AWAIT_TIME wskazuje, że kod oczekuje na zakończenie innego zadania. To opóźnienie występuje w instrukcji AWAIT języka C#. Gdy kod wykonuje kod AWAIT w języku C#:

  • Wątek odwija się i zwraca kontrolkę do puli wątków.
  • Nie ma zablokowanego wątku oczekującego na zakończenie await .

Jednak logicznie wątek, który wykonał await , jest "zablokowany", czekając na zakończenie operacji. Instrukcja AWAIT_TIME wskazuje zablokowany czas oczekiwania na zakończenie zadania.

Jeśli AWAIT_TIME wydaje się być w kodzie struktury zamiast kodu, program .NET Profiler może być wyświetlany:

  • Kod platformy używany do wykonywania funkcji AWAIT
  • Kod używany do rejestrowania danych telemetrycznych dotyczących funkcji AWAIT

Możesz usunąć zaznaczenie pola wyboru Zależności struktury w górnej części strony, aby wyświetlić tylko kod i ułatwić wyświetlanie miejsca pochodzenia funkcji AWAIT .

Zablokowany czas

BLOCKED_TIME wskazuje, że kod oczekuje na udostępnienie innego zasobu. Na przykład może to czekać na:

  • Obiekt synchronizacji
  • Wątek, który ma być dostępny
  • Żądanie zakończenia

Niezarządzany asynchroniczny

Aby można było śledzić wywołania asynchroniczne między wątkami, program .NET Framework emituje zdarzenia ETW i przekazuje identyfikatory działań między wątkami. Ponieważ kod niezarządzany (natywny) i niektóre starsze style kodu asynchronicznego nie mają tych zdarzeń i identyfikatorów działań, program .NET Profiler nie może śledzić wątku i funkcji uruchomionych w wątku. Ten element ma etykietę Unmanaged Async w stosie wywołań. Pobierz plik ETW, aby użyć narzędzia PerfView , aby uzyskać więcej szczegółowych informacji.

Czas procesora CPU

Procesor CPU jest zajęty wykonywaniem instrukcji.

Czas dysku

Aplikacja wykonuje operacje na dysku.

Czas sieci

Aplikacja wykonuje operacje sieciowe.

Gdy kolumna

Kolumna When to wizualizacja różnych przykładów inkluzywnych zebranych dla węzła w czasie. Łączny zakres żądania jest podzielony na przedziały czasu 32, w których gromadzą się próbki inkluzywne węzła. Każdy zasobnik jest reprezentowany jako pasek. Wysokość słupka reprezentuje skalowaną wartość. W przypadku następujących węzłów pasek reprezentuje zużycie jednego z zasobów w zasobniku:

  • Węzły oznaczone CPU_TIME lub BLOCKED_TIME.
  • Węzły z oczywistą relacją do korzystania z zasobu (na przykład procesora CPU, dysku lub wątku).

W przypadku tych metryk można uzyskać wartość większą niż 100%, zużywając wiele zasobów. Jeśli na przykład używasz dwóch procesorów CPU w średnim interwale, otrzymasz 200%.

Następne kroki

Dowiedz się, jak...