Debugowanie wysokiego użycia procesora CPU na platformie .NET Core
Ten artykuł dotyczy: ✔️ zestaw .NET Core 3.1 SDK i nowsze wersje
Z tego samouczka dowiesz się, jak debugować nadmierny scenariusz użycia procesora CPU. Korzystając z podanego przykładu ASP.NET Core repozytorium kodu źródłowego aplikacji internetowej, możesz celowo spowodować zakleszczenie. Punkt końcowy przestanie odpowiadać i gromadzić wątki. Dowiesz się, jak można używać różnych narzędzi do diagnozowania tego scenariusza z kilkoma kluczowymi elementami danych diagnostycznych.
Ten samouczek obejmuje następujące kroki:
- Badanie wysokiego użycia procesora CPU
- Określanie użycia procesora CPU za pomocą liczników dotnet-counter
- Używanie polecenia dotnet-trace do generowania śledzenia
- Wydajność profilu w programie PerfView
- Diagnozowanie i rozwiązywanie nadmiernego użycia procesora CPU
Wymagania wstępne
W tym samouczku są używane następujące elementy:
- Zestaw .NET Core 3.1 SDK lub nowsza wersja.
- Przykładowy element docelowy debugowania w celu wyzwolenia scenariusza.
- dotnet-trace do wyświetlania listy procesów i generowania profilu.
- dotnet-counters do monitorowania użycia procesora CPU.
Liczniki procesora CPU
Przed podjęciem próby zebrania danych diagnostycznych należy obserwować wysoki stan procesora CPU. Uruchom przykładową aplikację przy użyciu następującego polecenia z katalogu głównego projektu.
dotnet run
Aby znaleźć identyfikator procesu, użyj następującego polecenia:
dotnet-trace ps
Zanotuj identyfikator procesu z danych wyjściowych polecenia. Nasz identyfikator procesu to 22884
, ale Twój będzie inny. Aby sprawdzić bieżące użycie procesora CPU, użyj polecenia narzędzia dotnet-counters :
dotnet-counters monitor --refresh-interval 1 -p 22884
Jest refresh-interval
to liczba sekund między licznikami sondowania wartości procesora CPU. Dane wyjściowe będą podobne do następujących:
Press p to pause, r to resume, q to quit.
Status: Running
[System.Runtime]
% Time in GC since last GC (%) 0
Allocation Rate / 1 sec (B) 0
CPU Usage (%) 0
Exception Count / 1 sec 0
GC Heap Size (MB) 4
Gen 0 GC Count / 60 sec 0
Gen 0 Size (B) 0
Gen 1 GC Count / 60 sec 0
Gen 1 Size (B) 0
Gen 2 GC Count / 60 sec 0
Gen 2 Size (B) 0
LOH Size (B) 0
Monitor Lock Contention Count / 1 sec 0
Number of Active Timers 1
Number of Assemblies Loaded 140
ThreadPool Completed Work Item Count / 1 sec 3
ThreadPool Queue Length 0
ThreadPool Thread Count 7
Working Set (MB) 63
Po uruchomieniu aplikacji internetowej natychmiast po uruchomieniu procesor CPU nie jest w ogóle używany i jest zgłaszany pod adresem 0%
. Przejdź do api/diagscenario/highcpu
trasy za pomocą 60000
parametru trasy:
https://localhost:5001/api/diagscenario/highcpu/60000
Teraz uruchom ponownie polecenie dotnet-counters . Jeśli interesuje cię monitorowanie tylko cpu-usage
licznika, dodaj element "--counters System.Runtime[cpu-usage]" do poprzedniego polecenia. Nie jesteśmy pewni, czy procesor jest używany, więc będziemy monitorować tę samą listę liczników, co powyżej, aby sprawdzić, czy wartości liczników znajdują się w oczekiwanym zakresie dla naszej aplikacji.
dotnet-counters monitor -p 22884 --refresh-interval 1
Powinien zostać wyświetlony wzrost użycia procesora CPU, jak pokazano poniżej (w zależności od maszyny hosta oczekiwano różnego użycia procesora CPU):
Press p to pause, r to resume, q to quit.
Status: Running
[System.Runtime]
% Time in GC since last GC (%) 0
Allocation Rate / 1 sec (B) 0
CPU Usage (%) 25
Exception Count / 1 sec 0
GC Heap Size (MB) 4
Gen 0 GC Count / 60 sec 0
Gen 0 Size (B) 0
Gen 1 GC Count / 60 sec 0
Gen 1 Size (B) 0
Gen 2 GC Count / 60 sec 0
Gen 2 Size (B) 0
LOH Size (B) 0
Monitor Lock Contention Count / 1 sec 0
Number of Active Timers 1
Number of Assemblies Loaded 140
ThreadPool Completed Work Item Count / 1 sec 3
ThreadPool Queue Length 0
ThreadPool Thread Count 7
Working Set (MB) 63
W całym czasie trwania żądania użycie procesora CPU zostanie zatrzymane wokół zwiększonej wartości procentowej.
Napiwek
Aby zwizualizować jeszcze wyższe użycie procesora CPU, możesz wykonać ten punkt końcowy na wielu kartach przeglądarki jednocześnie.
W tym momencie można bezpiecznie powiedzieć, że procesor jest uruchomiony wyżej niż oczekiwano. Identyfikowanie skutków problemu jest kluczem do znalezienia przyczyny. Oprócz narzędzi diagnostycznych użyjemy efektu wysokiego użycia procesora CPU, aby znaleźć przyczynę problemu.
Analizowanie wysokiego użycia procesora CPU za pomocą profilera
Podczas analizowania aplikacji z wysokim użyciem procesora CPU potrzebne jest narzędzie diagnostyczne, które może zapewnić wgląd w działanie kodu. Typowym wyborem jest profiler i istnieją różne opcje profilera do wyboru. dotnet-trace
Może być używany we wszystkich systemach operacyjnych, jednak jego ograniczenia stronniczości bezpiecznego punktu i stosów wywołań tylko zarządzanych powodują bardziej ogólne informacje w porównaniu z profilerem obsługującym jądro, takich jak "wydajności" dla systemu Linux lub ETW dla systemu Windows. Jeśli badanie wydajności obejmuje tylko kod zarządzany, ogólnie dotnet-trace
będzie wystarczająca.
Narzędzie perf
może służyć do generowania profilów aplikacji platformy .NET Core. Pokażemy to narzędzie, chociaż można również użyć narzędzia dotnet-trace. Zamknij poprzednie wystąpienie przykładowego celu debugowania.
Ustaw zmienną DOTNET_PerfMapEnabled
środowiskową, aby spowodować utworzenie pliku w /tmp
katalogu przez aplikację map
.NET. Ten map
plik jest używany przez perf
program do mapowania adresów procesora CPU na funkcje generowane przez JIT według nazwy. Aby uzyskać więcej informacji, zobacz Eksportowanie map wydajności i zrzutów jit.
Uwaga
Program .NET 6 standardizuje prefiks DOTNET_
zamiast COMPlus_
zmiennych środowiskowych, które konfigurują zachowanie czasu wykonywania platformy .NET. COMPlus_
Jednak prefiks będzie nadal działać. Jeśli używasz poprzedniej wersji środowiska uruchomieniowego platformy .NET, nadal należy użyć prefiksu COMPlus_
dla zmiennych środowiskowych.
Uruchom przykładowy element docelowy debugowania w tej samej sesji terminalu.
export DOTNET_PerfMapEnabled=1
dotnet run
Ponownie przećwiczyć punkt końcowy interfejsu API wysokiego użycia procesora CPU (https://localhost:5001/api/diagscenario/highcpu/60000
). Gdy jest ono uruchamiane w ciągu 1-minutowego żądania, uruchom perf
polecenie przy użyciu identyfikatora procesu:
sudo perf record -p 2266 -g
Polecenie perf
uruchamia proces zbierania wydajności. Poczekaj około 20–30 sekund, a następnie naciśnij klawisze Ctrl+C , aby zakończyć proces zbierania. Możesz użyć tego samego perf
polecenia, aby wyświetlić dane wyjściowe śledzenia.
sudo perf report -f
Możesz również wygenerować graf płomienia przy użyciu następujących poleceń:
git clone --depth=1 https://github.com/BrendanGregg/FlameGraph
sudo perf script | FlameGraph/stackcollapse-perf.pl | FlameGraph/flamegraph.pl > flamegraph.svg
To polecenie generuje element flamegraph.svg
, który można wyświetlić w przeglądarce w celu zbadania problemu z wydajnością:
Analizowanie danych wysokiego użycia procesora CPU za pomocą programu Visual Studio
Wszystkie pliki *.nettrace można analizować w programie Visual Studio. Aby przeanalizować plik *.nettrace systemu Linux w programie Visual Studio, przenieś plik *.nettrace, oprócz innych niezbędnych dokumentów, na maszynę z systemem Windows, a następnie otwórz plik *.nettrace w programie Visual Studio. Aby uzyskać więcej informacji, zobacz Analizowanie danych użycia procesora CPU.
Zobacz też
- dotnet-trace do list procesów
- dotnet-counters do sprawdzania użycia pamięci zarządzanej
- dotnet-dump do zbierania i analizowania pliku zrzutu
- dotnet/diagnostics