Share via


.NET Core'da yüksek CPU kullanımında hata ayıklama

Bu makale şunlar için geçerlidir: ✔️ .NET Core 3.1 SDK ve sonraki sürümler

Bu öğreticide, aşırı CPU kullanımı senaryosunda hata ayıklamayı öğreneceksiniz. Core web uygulaması kaynak kodu deposu ASP.NET sağlanan örneği kullanarak, kasıtlı olarak kilitlenmeye neden olabilirsiniz. Uç nokta yanıt vermeyi durdurur ve iş parçacığı birikimiyle karşılaşır. Bu senaryoya tanılama verilerinin birkaç önemli parçasıyla tanılamak için çeşitli araçları nasıl kullanabileceğinizi öğreneceksiniz.

Bu öğreticide şunları yapacaksınız:

  • Yüksek CPU kullanımını araştırma
  • dotnet-counters ile CPU kullanımını belirleme
  • İzleme oluşturma için dotnet-trace kullanma
  • PerfView'da profil performansı
  • Aşırı CPU kullanımını tanılama ve çözme

Önkoşullar

Öğreticide aşağıdakiler kullanılır:

CPU sayaçları

Tanılama verilerini toplamaya çalışmadan önce yüksek BIR CPU koşulu gözlemlemeniz gerekir. Proje kök dizininden aşağıdaki komutu kullanarak örnek uygulamayı çalıştırın.

dotnet run

İşlem kimliğini bulmak için aşağıdaki komutu kullanın:

dotnet-trace ps

Komut çıkışınızdan işlem kimliğini not alın. İşlem kimliğimiz şeklindeydi 22884, ancak sizinki farklı olacaktır. Geçerli CPU kullanımını denetlemek için dotnet-counters tool komutunu kullanın:

dotnet-counters monitor --refresh-interval 1 -p 22884

, refresh-interval sayaç yoklama CPU değerleri arasındaki saniye sayısıdır. Çıktının aşağıdakine benzer olması gerekir:

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

Web uygulaması çalışırken, başlangıçtan hemen sonra CPU hiç tüketilmiyor ve konumunda 0%bildiriliyor. api/diagscenario/highcpu yol parametresi olarak ile 60000 yola gidin:

https://localhost:5001/api/diagscenario/highcpu/60000

Şimdi dotnet-counters komutunu yeniden çalıştırın. Yalnızca cpu-usage sayacı izlemek istiyorsanız, önceki komuta '--counters System.Runtime[cpu-usage]' ekleyin. CPU'nun tüketilip tüketilmediğini emin olmadığından emin olmadığından, sayaç değerlerinin uygulamamız için beklenen aralıkta olduğunu doğrulamak için yukarıdaki sayaçların listesini izleyeceğiz.

dotnet-counters monitor -p 22884 --refresh-interval 1

Aşağıda gösterildiği gibi CPU kullanımında bir artış görmeniz gerekir (konak makineye bağlı olarak değişen CPU kullanımı beklenmelidir):

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

İsteğin süresi boyunca CPU kullanımı artan yüzdenin üzerine gelir.

Bahşiş

Daha da yüksek bir CPU kullanımını görselleştirmek için bu uç noktayı aynı anda birden çok tarayıcı sekmesinde kullanabilirsiniz.

Bu noktada, CPU'nin beklediğinizden daha yüksek çalıştığını güvenle söyleyebilirsiniz. Sorunun etkilerini belirlemek, nedeni bulmanın anahtarıdır. Sorunun nedenini bulmak için tanılama araçlarına ek olarak yüksek CPU tüketiminin etkisini kullanacağız.

Profil Oluşturucu ile Yüksek CPU'ları Analiz Etme

Yüksek CPU kullanımına sahip bir uygulamayı analiz ederken, kodun ne yaptığına ilişkin içgörüler sağlayabilen bir tanılama aracına ihtiyacınız vardır. Her zamanki seçim bir profil oluşturucudur ve aralarından seçim yapabileceğiniz farklı profil oluşturucu seçenekleri vardır. dotnet-trace tüm işletim sistemlerinde kullanılabilir, ancak güvenli nokta sapmaları ve yalnızca yönetilen çağrı yığınları sınırlamaları Linux için 'perf' veya Windows için ETW gibi çekirdek kullanan bir profil oluşturucuya kıyasla daha genel bilgiler sağlar. Performans araştırmanız yalnızca yönetilen kod içeriyorsa, genel olarak dotnet-trace yeterli olacaktır.

Araç perf , .NET Core uygulama profilleri oluşturmak için kullanılabilir. Dotnet-trace de kullanılabilse de bu aracı göstereceğiz. Örnek hata ayıklama hedefinin önceki örneğinden çıkın.

.NET uygulamasının DOTNET_PerfMapEnabled dizinde bir map dosya oluşturmasına neden olacak ortam değişkenini /tmp ayarlayın. Bu map dosya, CPU adreslerini ada göre JIT tarafından oluşturulan işlevlere eşlemek için tarafından perf kullanılır. Daha fazla bilgi için bkz . Performans haritalarını ve jit dökümlerini dışarı aktarma.

Dekont

.NET 6, .NET çalışma zamanı davranışını yapılandıran ortam değişkenleri yerine COMPlus_ ön eki DOTNET_ standartlaştırır. Ancak ön COMPlus_ ek çalışmaya devam eder. .NET çalışma zamanının önceki bir sürümünü kullanıyorsanız, ortam değişkenleri için ön eki kullanmaya COMPlus_ devam etmelisiniz.

Örnek hata ayıklama hedefini aynı terminal oturumunda çalıştırın.

export DOTNET_PerfMapEnabled=1
dotnet run

Yüksek CPU API uç noktasını (https://localhost:5001/api/diagscenario/highcpu/60000) yeniden kullanın. 1 dakikalık istek içinde çalışırken, komutu işlem kimliğiniz ile çalıştırın perf :

sudo perf record -p 2266 -g

komutu perf performans toplama işlemini başlatır. Yaklaşık 20-30 saniye çalışmasına izin verin, ardından toplama işleminden çıkmak için Ctrl+C tuşlarına basın. İzlemenin çıkışını görmek için aynı perf komutu kullanabilirsiniz.

sudo perf report -f

Aşağıdaki komutları kullanarak bir alev grafiği de oluşturabilirsiniz:

git clone --depth=1 https://github.com/BrendanGregg/FlameGraph
sudo perf script | FlameGraph/stackcollapse-perf.pl | FlameGraph/flamegraph.pl > flamegraph.svg

Bu komut, performans sorununu araştırmak için tarayıcıda görüntüleyebileceğiniz bir flamegraph.svg oluşturur:

Flame graph SVG image

Visual Studio ile Yüksek CPU Verilerini Çözümleme

Tüm *.nettrace dosyaları Visual Studio'da analiz edilebilir. Visual Studio'da bir Linux *.nettrace dosyasını analiz etmek için, *.nettrace dosyasını, diğer gerekli belgelere ek olarak bir Windows makinesine aktarın ve ardından *.nettrace dosyasını Visual Studio'da açın. Daha fazla bilgi için bkz . CPU Kullanım Verilerini Çözümleme.

Ayrıca bkz.

Sonraki adımlar