還記得乙個關於製藥廠業務系統CPU爆炸的NET分析嗎

Mondo 科技 更新 2024-01-30

前段時間,有個朋友來找我,說他們的程式CPU爆炸了,讓我幫忙看看是怎麼回事?解決這個問題的最好方法是抓取乙個轉儲並扔給我,推薦的工具是使用 procdump 來自動捕獲。

還是老規矩,想找到這個答案,可以用!tp 命令。

0:044> !tplogstart: 1logsize: 200cpu utilization: 88 %worker thread: total: 8 running: 4 idle: 4 maxlimit: 1023 minlimit: 4work request in queue: 0---number of timers: 2---completion port thread:total: 2 free: 2 maxfree: 8 currentlimit: 2 maxlimit: 1000 minlimit: 4
從卦象資料來看,目前的CPU確實已經達到了88%,然後我們觀察一下這個程式的機器CPU是否強大,就可以使用了!CPUID 觀察。

0:044> !cpuidcp f/m/s manufacturer mhz 0 6,94,3 genuineintel 3192 1 6,94,3 genuineintel 3192 2 6,94,3 genuineintel 3192 3 6,94,3 genuineintel 3192
從卦象來看,尼瑪也是4核,有點弱,但也是高利潤的製藥廠,所以挑剔。

導致CPU爆裂的因素有很多,沒有標準答案,需要自己找原因,首先我們來觀察一下這個程式中的執行緒數,就可以使用了!t 命令。

0:044> !tthreadcount: 451unstartedthread: 0backgroundthread: 443pendingthread: 0deadthread: 1hosted runtime: no lock dbg id osid threadobj state gc mode gc alloc context domain count apt exception 0 1 22b8 04ce8728 26020 preemptive 18e5c92c:18e5e4dc 04c86c20 -00001 sta 3 2 17c8 04b25768 2b220 preemptive 18caf3a0:18cb1374 04c86c20 -00001 mta (finalizer) 4 4 238c 04c0cdd8 202b020 preemptive 18e45d88:18e464dc 04c86c20 -00001 mta 5 5 230c 0a6c37a0 202b020 preemptive 18dac318:18dac47c 04c86c20 -00001 mta 6 6 23a0 0a70e620 202b220 preemptive 00000000:00000000 04c86c20 -00001 mta ..
從卦中的資料來看,目前有451個執行緒,其中443個是後台執行緒,再加上剛剛!TP 看到的執行緒池中只有 8 個執行緒,這意味著該程式中有 400+ 個執行緒是通過 new 執行緒直接建立的,這個資訊比較可疑。

下乙個想法是使用 *e !clrstack 命令觀察每個執行緒此時在做什麼,一旦輸入命令,刷子就需要很長時間。

0:044> ~e !clrstack...os thread id: 0x220c (18)child sp ip call site184cf614 77dd19dc [helpermethodframe: 184cf614] system.threading.thread.sleepinternal(int32)184cf680 141975f4 system.threading.thread.sleep(int32) [/_/src/libraries/system.private.corelib/src/system/threading/thread.cs @ 357]184cf694 165055b9 xxx.actionthread`1[[xxx]].loop()184cf878 74467741 system.threading.thread+starthelper.callback(system.object) [/_/src/libraries/system.private.corelib/src/system/threading/thread.cs @ 42]184cf888 7446fca1 system.threading.executioncontext.runinternal(system.threading.executioncontext, system.threading.contextcallback, system.object) [/_/src/libraries/system.private.corelib/src/system/threading/executioncontext.cs @ 183]184cf8c0 74466742 system.threading.thread.startcallback() /_/src/coreclr/system.private.corelib/src/system/threading/thread.coreclr.cs @ 105]184cfa14 74cbc29f [debuggeru2mcatchhandlerframe: 184cfa14] .
卦象中線棧上沒有特別明顯的業務功能,大多停留在螺紋上sleepinternal,這讓我感到困惑。

CPU不能無緣無故地爆炸,總是那些執行緒被提公升,但這個程式中的大多數執行緒都線上程中Sleepinternal,說他們可以炸毀 CPU 有點牽強。

但問題必須解決,在沒有突破的情況下,你只能咬緊牙關sleepinternal 強行突破,先用 ctrl+f 搜尋 sleepinternal 卡住了多少個執行緒,截圖如下:

尼瑪,幾乎所有的執行緒都在休眠,一般來說,有這麼多執行緒在休眠也是少數,再畫個執行緒看看業務方法是怎麼休眠的,參考如下:

我發現這個迴圈方法中有很多睡眠(1),當我看到這個時,我突然想到了高頻上下文切換導致的CPU爆炸。

此**指令接下來停止在哪種方法?您可以反編譯 loop 方法。

0:047> !clrstackos thread id: 0xad8 (47)child sp ip call site20b5f434 77dd19dc [helpermethodframe: 20b5f434] system.threading.thread.sleepinternal(int32)20b5f4a0 141975f4 system.threading.thread.sleep(int32) [/_/src/libraries/system.private.corelib/src/system/threading/thread.cs @ 357]20b5f4b4 1f123c71 xxx.actionthread`1[[xxx].loop()20b5f698 74467741 system.threading.thread+starthelper.callback(system.object) [/_/src/libraries/system.private.corelib/src/system/threading/thread.cs @ 42]20b5f6a8 1baab7da system.threading.executioncontext.runinternal(system.threading.executioncontext, system.threading.contextcallback, system.object) [/_/src/libraries/system.private.corelib/src/system/threading/executioncontext.cs @ 183]20b5f6e0 74466742 system.threading.thread.startcallback() /_/src/coreclr/system.private.corelib/src/system/threading/thread.coreclr.cs @ 105]20b5f834 74cbc29f [debuggeru2mcatchhandlerframe: 20b5f834] 0:047> !u /d 1f123c71normal jit generated codexxx.actionthread`1[xxx].loop()iladdr is 0a324040 pimport is 08ad6468begin 1f123c10, size abd1f123c10 55 push ebp1f123c11 8bec mov ebp,esp1f123c13 57 push edi1f123c14 56 push esi1f123c15 81ecd4010000 sub esp,1d4h1f123c1b c5f877 vzeroupper1f123c1e c5d857e4 vxorps xmm4,xmm4,xmm41f123c22 c5fa7fa524feffff vmovdqu xmmword ptr [ebp-1dch],xmm41f123c2a c5fa7fa534feffff vmovdqu xmmword ptr [ebp-1cch],xmm41f123c32 b850feffff mov eax,0fffffe50h1f123c37 c5fa7f6405f4 vmovdqu xmmword ptr [ebp+eax-0ch],xmm41f123c3d c5fa7f640504 vmovdqu xmmword ptr [ebp+eax+4],xmm41f123c43 c5fa7f640514 vmovdqu xmmword ptr [ebp+eax+14h],xmm41f123c49 83c030 add eax,30h...1f123c5a e84115cc55 call coreclr!jit_dbgisjustmycode (74de51a0)1f123c5f 90 nop1f123c60 90 nop1f123c61 e9300a0000 jmp xxx.actionthread.loop+0xa86 (1f124696)1f123c66 90 nop1f123c67 b901000000 mov ecx,11f123c6c e87f54eaea call 09fc90f0 (system.threading.thread.sleep(int32), mdtoken: 06002d01)>>1f123c71 90 nop...
通過卦象中的>>,我們可以確認很多方法都在while(!base.isterminated),如果 sleep(1) 的執行緒數較少,可能不是問題,但它無法承受超過 400 個執行緒一起玩,最後是高頻上下文切換導致的 CPU 爆炸。

在 sleep(1) 中會有乙個 CPU 的等待佇列、乙個就緒佇列和乙個 timer ktimer 核心物件,因為 Windows 原始碼不是公開的,所以內部還是比較有趣的,你可以使用 !PCR 命令觀察 CPU 的背包。

lkd> !pcr 0kpcr for processor 0 at fffff8058023c000: major 1 minor 1 nttib.exceptionlist: fffff80589089fb0 nttib.stackbase: fffff80589088000 nttib.stacklimit: 000000137e1fa158 nttib.subsystemtib: fffff8058023c000 nttib.version: 000000008023c180 nttib.userpointer: fffff8058023c870 nttib.selftib: 000000137dfe0000 selfpcr: 0000000000000000 prcb: fffff8058023c180 irql: 0000000000000000 ..currentthread: ffff910c66906080 nextthread: 0000000000000000 idlethread: fffff80583d27a00 dpcqueue: lkd> dt nt!_kprcb fffff8058023c180 +0x008 currentthread : 0xffff910c`66906080 _kthread +0x010 nextthread : null) +0x018 idlethread : 0xfffff805`83d27a00 _kthread ..0x7c00 waitlisthead : list_entry [ 0xffff910c`5ec30158 - 0xffff910c`628b1158 ] 0x7c80 dispatcherreadylisthead : 32] _list_entry [ 0xfffff805`80243e00 - 0xfffff805`80243e00 ]
上面的 [32] 是乙個包含 32 個優先順序的陣列佇列,等待執行緒。

有了上面的分析結果,最後就是告訴你的朋友做以下兩件事:

減少執行緒sleep(1) 的執行緒參與數。 盡量用1->50來緩解,當然越大越好。 這次CPU爆裂還是挺有意思的,不是業務方式導致的爆裂,而是睡眠(1)導致的大量高頻上下文切換,有點意思,留下這篇文章給大家避坑!

相關問題答案

    這一次,徐的“屁股”要被剝光了,三性關係怎麼能為自己辯解呢?

    江蘇銀行一名女職工爆料稱自己曾遭性騷擾,事件引發熱議。一位徐姓女員工向名同事講述了她的遭遇 她說,她被領導人許某某逼迫,要求她在一年內發生三次性關係。事發後,江蘇銀行作簡報,稱徐某為普通員工 而男主馬某某則因個人問題被免職。然而,事件的內幕似乎比看起來要複雜得多,引發了許多問題。徐某的報道內容和她對...

    這一次,徐的“屁股”要被剝光了,三性關係怎麼能為自己辯解呢?

    性騷擾在中國是乙個普遍存在的社會問題,尤其是在職場中,許多女員工不得不忍受老闆或同事的不當行為,甚至被迫發生性關係。這種現象不僅侵犯了女性的人格和尊嚴,也影響了職場的公平正義。近日,一起江蘇某銀行性騷擾案引發廣泛關注和討論。一位徐姓女員工在微信群裡爆料,稱自己一年內被領導徐某某強迫發生三次性關係,而...

    這一次,徐某的“褲子”要脫光了,三性關係怎麼能為自己辯解呢?

    江蘇銀行月日,內部員工徐某公開了自己被領導馬某某強迫發生性關係的經歷。根據徐的說法,她在年發生了三次性關係,都發生在馬的車裡。馬某某在年初 夏天和月日與徐發生性關係。事件發生後 江蘇銀行進行了簡報,報告顯示,徐江蘇銀行鎮江分公司業務部的一名普通員工,馬某某是她的團隊經理,兩人之間存在從屬關係。從事態...

    這一次,徐某的“內衣”要脫光了,三性關係怎麼能為自己辯解呢?

    江蘇銀行內部發生的性醜聞再次引發公眾關注。一名女員工徐某向微信群裡的同事爆料,她被徐某某強行發生了三次性關係,而這些性行為都發生在徐某的車裡。這一事件引起了廣泛關注,也讓人們重新意識到職場性騷擾問題。然而,事件的真相究竟是什麼?我們需要重新審視這一系列事件並深入研究細節 月日,錄製了題為 大公司奮鬥...

    還記得云然全家試駕的令人羨慕的經歷

    早在今年月,比亞迪就發布了全球首款新能源專屬智慧型車身控制系統 雲源 nian 在宣發會上介紹這套技術非常 神秘 它不是單一的技術,而是比亞迪完全自主研發的新能源平台車身控制系統合成。根據不同的硬體基礎和產品定位,還分為雲南 C YUNLIN A YUNLIN P YUNLIN X等多種形態,從舒適...