.Net Core服務診斷排查

chaney1992發表於2021-12-19

前言:

 近期在專案中出現了幾次服務記憶體資源佔用較高的情況,特回顧梳理下排查過程以及對相應問題的排查方法總結。

一、Dump抓取

 抓取dump的方式有多種,下面介紹幾種常用的:

  1. 工作管理員中找到程式程式,右鍵選單:建立轉儲存檔案

   

   注意:需要以程式執行的位數執行工作管理員抓取Dump

  2. DotNet 全域性工具:dotnet-dump;工具可適用於Windows、Linux、macOS平臺

   a) 安裝全域性dotnet-dump工具:

dotnet tool install --global dotnet-dump

   b) 使用該工具抓取dump:

dotnet-dump collect [-h|--help] [-p|--process-id] [-n|--name] [--type] [-o|--output] [--diag]
    • -h|--help:顯示命令列幫助。
    • -p|--process-id <PID>:指定從中收集轉儲的程式的 ID 號。
    • -n|--name <name>:指定從中收集轉儲的程式的名稱。
    • --type <Full|Heap|Mini>:指定轉儲型別,它確定從程式收集的資訊的型別。 有三種型別:Full - 最大的轉儲,包含所有記憶體(包括模組映像)。Heap - 大型且相對全面的轉儲,其中包含模組列表、執行緒列表、所有堆疊、異常資訊、控制程式碼資訊和除對映影像以外的所有記憶體。Mini - 小型轉儲,其中包含模組列表、執行緒列表、異常資訊和所有堆疊。如果未指定,則 Full 為預設型別。
    • -o|--output <output_dump_path>:應在其中寫入收集的轉儲的完整路徑和檔名。如果未指定:在 Windows 上預設為 .\dump_YYYYMMDD_HHMMSS.dmp ;在 Linux 上預設為 ./core_YYYYMMDD_HHMMSS ;YYYYMMDD 為年/月/日,HHMMSS 為小時/分鐘/秒。
    • --diag:啟用轉儲收集診斷日誌記錄。

  3、ProcDump抓取Dump工具:自動抓取

    命令語法:

procdump.exe [-mm] [-ma] [-mp] [-mc Mask] [-md Callback_DLL] [-mk]
             [-n Count]
             [-s Seconds]
             [-c|-cl CPU_Usage [-u]]
             [-m|-ml Commit_Usage]
             [-p|-pl Counter_Threshold]
             [-h]
             [-e [1 [-g] [-b]]]
             [-l]
             [-t]
             [-f  Include_Filter, ...]
             [-fx Exclude_Filter, ...]
             [-o]
             [-r [1..5] [-a]]
             [-at Timeout]
             [-wer]
             [-64]
             {
                 {{[-w] Process_Name | Service_Name | PID} [Dump_File | Dump_Folder]}
             |
                 {-x Dump_Folder Image_File [Argument, ...]}
             }

   引數說明:    

引數說明
-a 避免中斷。 需要 -r。 如果觸發器會導致目標因超出併發轉儲限制而長時間掛起,將跳過觸發器。
-at 避免超時中斷。 在 N 秒時取消觸發器的集合。
-b 將除錯斷點視為異常 (否則忽略它們) 。
-c CPU 閾值,用於建立程式的轉儲。
-cl CPU 閾值,低於該閾值可建立程式的轉儲。
-d 呼叫指定 DLL 的名為 MiniDumpCallbackRoutine 的小型轉儲回撥例程。
-e 當程式遇到未經處理異常時編寫轉儲。 包括 1,以在出現第一機會異常時建立轉儲。
-f 篩選第一個可能異常。 支援萬用字元 (*) 。 若要僅顯示名稱而不進行轉儲,請使用空白 ("") 篩選器。
-fx 篩選 (排除) 異常內容和除錯日誌記錄。 支援萬用字元。
-g 在託管程式中作為本機偵錯程式執行, (互操作) 。
-h 如果程式有掛起的視窗, (在至少 5 秒未響應視窗訊息時寫入) 。
-i 將 ProcDump 安裝為 AeDebug 事後偵錯程式。 僅支援使用 -ma、-mp、-d 和 -r 作為附加選項。
-k 克隆到 (-r) 或轉儲收集結束時終止程式
-l 顯示程式的除錯日誌記錄。
-m 記憶體提交閾值(以 MB 為單位)用於建立轉儲。
-ma 編寫包含所有程式記憶體的轉儲檔案。 預設轉儲格式僅包含執行緒和處理資訊。
-mc 編寫自定義轉儲檔案。 包括由指定的十六進位制MINIDUMP_TYPE掩碼 (記憶體) 。
-md 編寫回撥轉儲檔案。 包括由指定 DLL 的名為 MiniDumpCallbackRoutine 的 MiniDumpWriteDump 回撥例程定義的記憶體。
-mk 同時編寫核心轉儲檔案。 包括程式中執行緒的核心堆疊。 使用克隆 (-r) 時,OS 不支援核心轉儲 (-mk) 。 使用多個轉儲大小時,會針對每個轉儲大小執行核心轉儲。
-ml 當記憶體提交低於指定的 MB 值時觸發。
-mm 使用預設模式編寫 (轉儲) 。
-mp 使用執行緒和控制程式碼資訊以及所有讀/寫程式記憶體編寫轉儲檔案。 為了最大程度地減小轉儲大小,將搜尋大於 512MB 的記憶體區域,如果找到,則排除最大的區域。 記憶體區域是大小相同的記憶體分配區域的集合。 刪除此記憶體 (快取) 將Exchange和SQL Server轉儲減少 90% 以上。
-n 退出前要寫入的轉儲數。
-o 覆蓋現有的轉儲檔案。
-p 超過閾值時,對指定效能計數器觸發。 注意:若要在程式有多個例項執行時指定程式計數器,請使用具有以下語法的程式 ID:"\Process (< name > _ < pid >) \counter"
-pl 當效能計數器低於指定值時觸發。
-r 使用克隆進行轉儲。 併發限制是可選的 (預設為 1,最大為 5) 。
警告:高併發值可能會影響系統效能。
- Windows 7:使用反射。 OS 不支援 -e。
- Windows 8.0:使用反射。 OS 不支援 -e。
- Windows 8.1+:使用 PSS。 支援所有觸發器型別。
-s 寫入轉儲之前連續秒 (預設值為 10) 。
-t 在程式終止時寫入轉儲。
-u 將 CPU 使用率視為與 -c (一) 。
作為唯一選項,解除安裝 ProcDump 作為事後偵錯程式。
-w 等待指定的程式啟動(如果該程式未執行)。
-wer 將 (最大) 排隊到Windows 錯誤報告。
-x 使用可選引數啟動指定的映像。 如果是應用商店應用程式或包,ProcDump 將在下次啟用時啟動, (啟用) 。
-64 預設情況下,在 64 位程式上執行時,ProcDump 將捕獲 32 位程式的 32 位Windows。 此選項將替代 以建立 64 位轉儲。 僅用於 WOW64 子系統除錯。
-? 使用 -? -e 檢視示例命令列。

   示例:

    當程式在 5 秒鐘內 CPU 使用率超過 50% 時,最多寫入 2 個名為"w3wp"的程式的微型轉儲:

procdump -ma -s 5 -n 2 -c 50 w3wp

二、Dump分析

  根據前面幾方式得到的Dump檔案,下一步就是對Dump進行分析確認問題原因:

 1、Windbug Preview 分析:

  Windbg Preview 是windows平臺上的一款相當強大的除錯工具,可以從msdn網站下載得到,最新版本包含在windows sdk中,預設會被安裝在C:\Program Files\Debugging Tools for Windows 目錄中,可以直接把這個目錄打包複製到其它機器上使用。

  Windbug常用命令:

    • !analyze -v    自動分析dump
    • kv    檢視棧回溯
    • .ecxr    顯示當前異常上下文
    • .cxr    切換異常幀上下文
    • .exr    顯示異常資訊
    • .frame    設定當前棧幀
    • dv    顯示當前棧幀區域性變數
    • dd    顯示記憶體中的資料
    • r    檢視暫存器
    • lmvm    檢視模組詳細資訊
    • r    可以顯示系統崩潰時的暫存器,和最後的命令狀態
    • dd    顯示當前記憶體地址,dd 引數:顯示引數處的記憶體
    • u    可以顯示反彙編的指令
    • kb    顯示call stack 內容

   

 2、VS分析Dump:

  a) 使用VS開啟dump檔案:

   

 可以看到該dump的基本資訊,接下來設定符號檔案:

   

b) 分析Dump中記憶體情況:除錯託管記憶體

 

    可以看到當前託管資源中記憶體佔用情況,如果有多個dump還可以對比dump中記憶體增長變化

   檢視物件內容:

   

c) 檢視當前執行的程式列表:(設定了符號檔案後可以檢視當前堆疊資訊,以及跳轉到程式碼邏輯)

  

 3、dotnet-dump分析:

  分析命令:

dotnet-dump analyze <dump_path> [-h|--help] [-c|--command]

  SOS命令支援:

命令函式
soshelp|help 顯示所有可用命令
soshelp|help <command> 執行指定的命令。
exit|quit 退出互動模式。
clrstack <arguments> 僅提供託管程式碼的堆疊跟蹤。
clrthreads <arguments> 列出正在執行的託管執行緒。
dumpasync <arguments> 顯示有關垃圾回收堆上非同步狀態機的資訊。
dumpassembly <arguments> 顯示有關指定地址處程式集的詳細資訊。
dumpclass <arguments> 顯示有關指定地址處的 EEClass 結構的資訊。
dumpdelegate <arguments> 顯示有關指定地址處的委託的資訊。
dumpdomain <arguments> 顯示所有 AppDomain 和指定域中的所有程式集的資訊。
dumpheap <arguments> 顯示有關垃圾回收堆的資訊和有關物件的收集統計資訊。
dumpil <arguments> 顯示與託管方法關聯的 Microsoft 中間語言 (MSIL)。
dumplog <arguments> 將記憶體中壓力日誌的內容寫入到指定檔案。
dumpmd <arguments> 顯示有關指定地址處的 MethodDesc 結構的資訊。
dumpmodule <arguments> 顯示有關指定地址處的模組的資訊。
dumpmt <arguments> 顯示有關指定地址處的 MethodTable 的資訊。
dumpobj <arguments> 顯示有關位於指定地址處的物件的資訊。
dso|dumpstackobjects <arguments> 顯示在當前堆疊的邊界內找到的所有託管物件。
eeheap <arguments> 顯示有關內部執行時資料結構所使用的程式記憶體的資訊。
finalizequeue <arguments> 顯示所有已進行終結註冊的物件。
gcroot <arguments> 顯示有關對指定地址處的物件的引用(或根)的資訊。
gcwhere <arguments> 顯示傳入引數在 GC 堆中的位置。
ip2md <arguments> 顯示 JIT 程式碼中指定地址處的 MethodDesc 結構。
histclear <arguments> 釋放由 hist* 命令系列使用的任何資源。
histinit <arguments> 從儲存在除錯物件中的壓力日誌初始化 SOS 結構。
histobj <arguments> 顯示與 <arguments> 相關的垃圾回收壓力日誌重定位。
histobjfind <arguments> 顯示在指定地址處引用物件的所有日誌項。
histroot <arguments> 顯示與指定根的提升和重定位相關的資訊。
lm|modules 顯示程式中的本機模組。
name2ee <arguments> 顯示 <argument> 的 MethodTable 和 EEClass 結構。
pe|printexception <arguments> 顯示從 Exception 類派生的 <argument> 的任何物件。
setsymbolserver <arguments> 啟用符號伺服器支援
syncblk <arguments> 顯示 SyncBlock 持有者資訊。
threads|setthread <threadid> 設定或顯示 SOS 命令的當前執行緒 ID。

   例如:

dotnet-dump analyze "w3wp (2).DMP"

三、案例:

  問題現象:xxx服務請求響應耗時較長,導致業務無法正常開展

  排查過程:

   1、檢視記憶體情況,Oracle連線數量較大

    

   2、檢視執行緒中都為Oracle連線等待:

    

    3、最終確認請求被卡到了Oracle處理

四、總結

  1、在排查服務相關問題時,分析dump方式是最直接的方式;而vs方式分析dump是最直接、方便、簡單的方式。

  2、通過windbug分析dump是最完整的方式

參考:

  windbg命令

相關文章