<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      記一次 .NET 某無語的電商采集系統(tǒng) CPU爆高分析

      一:背景

      1. 講故事

      前段時間有位朋友微信上找到我,說他們docker中的采集程序出現(xiàn)了CPU爆高的情況,讓我?guī)兔聪略趺椿厥拢约鹤チ藗€dump,感覺這位朋友動手能力還是比較強的,可能調試這塊知識不熟悉,不知道如何分析,既然找到我,那就給他分析下吧。

      二:CPU爆高分析

      1. 為什么會爆高

      在動手觀察CPU是否爆高之前,我一般都會先看一下這個cpu的能力怎么樣,在 windows 上相信大家都知道用 !cpuid 輕松觀察,但在 linux 上相對來說麻煩點,但也有兩種方式。

      1. 觀察 heap 個數(shù)

      由于是網(wǎng)站類型,默認是 servergc,而servergc有一個特性就是堆個數(shù)與邏輯核保持一致,所以觀察heap的個數(shù)可以間接得到,使用 !eeversion!eeheap -gc 命令,輸出如下:

      
      0:000> !eeversion
      4.700.20.51601 (3.x runtime)
      4.700.20.51601 @Commit: d989459717cbce34262060c4b8b949185033e379
      Server mode with 2 gc heaps
      SOS Version: 8.0.10.10501 retail build
      
      0:000> !eeheap -gc
      
      ========================================
      Number of GC Heaps: 2
      ----------------------------------------
      Heap 0 (0000000000cd4aa0)
      generation 0 starts at 7f509cc107d8
      generation 1 starts at 7f509cb84f80
      generation 2 starts at 7f509bfff000
      ephemeral segment allocation context: none
      Small object heap
               segment            begin        allocated        committed allocated size       committed size      
          7f509bffe000     7f509bfff000     7f509ccccfa8     7f509cec0000 0xccdfa8 (13426600)  0xec2000 (15474688) 
      Large object heap starts at 7f529bfff000
               segment            begin        allocated        committed allocated size       committed size      
          7f529bffe000     7f529bfff000     7f529c30c268     7f529c30d000 0x30d268 (3199592)   0x30f000 (3207168)  
      ------------------------------
      Heap 1 (0000000000d30950)
      generation 0 starts at 7f519cf7fcb0
      generation 1 starts at 7f519cf10788
      generation 2 starts at 7f519bfff000
      ephemeral segment allocation context: none
      Small object heap
               segment            begin        allocated        committed allocated size       committed size      
          7f519bffe000     7f519bfff000     7f519d018728     7f519d1fe000 0x1019728 (16881448) 0x1200000 (18874368)
      Large object heap starts at 7f52abfff000
               segment            begin        allocated        committed allocated size       committed size      
          7f52abffe000     7f52abfff000     7f52ac45bb10     7f52ac45c000 0x45cb10 (4573968)   0x45e000 (4579328)  
      ------------------------------
      GC Allocated Heap Size:    Size: 0x2451448 (38081608) bytes.
      GC Committed Heap Size:    Size: 0x282f000 (42135552) bytes.
      
      

      從卦中可以看到,當前heap=2,尼瑪。。。這 docker 只有兩個核呀。。。。這跑啥不都得cpu爆高嘛。。。

      有一些基礎的朋友可能會立即反駁,heapcount 是可以通過外部手段改的,言外之意就是你看到的可能是幻象。。。那到底是不是幻象呢?這就需要用第二種辦法了。。。

      1. 觀察 coreclr 源碼

      在 coreclr 中其實有大量的全局變量,只要你讀過相應的源碼,相信很快就能找到一個全局變量 g_num_processors ,參考如下:

      
      0:000> x libcoreclr!*process*
      00007f53`45b6e928 libcoreclr!g_num_processors = 2
      
      

      從卦中可以看到,確實當前邏輯核=2,這個是無法修改的。。。

      2. 朋友的質疑

      當知道cpucore=2的事實之后,我就不想分析了, 跑一個線程就能把cpu干一半,這讓我分析個啥。。。告知完朋友之后,讓他加邏輯核來解決,但朋友提出了自己的質疑,說他的程序之前CPU不高,為什么現(xiàn)在就高了?希望我能找到問題代碼。。。

      既然要找原因,那就到各個線程看看有沒有特別明顯的爆高代碼,使用 ~*e !clrstack 命令,仔細觀察了下,也沒有特別明顯的,只有一些Socket,Octopus,SqlServer 等,輸出如下:

      
      0:000> ~*e !clrstack
      ...
      OS Thread Id: 0x1b (19)
              Child SP               IP Call Site
      00007F5069FF8CE0 00007f534654f3c7 [InlinedCallFrame: 00007f5069ff8ce0] Interop+Sys.ReceiveMessage(System.Runtime.InteropServices.SafeHandle, MessageHeader*, System.Net.Sockets.SocketFlags, Int64*)
      00007F5069FF8CE0 00007f52d082d7db [InlinedCallFrame: 00007f5069ff8ce0] Interop+Sys.ReceiveMessage(System.Runtime.InteropServices.SafeHandle, MessageHeader*, System.Net.Sockets.SocketFlags, Int64*)
      00007F5069FF8CD0 00007f52d082d7db ILStubClass.IL_STUB_PInvoke(System.Runtime.InteropServices.SafeHandle, MessageHeader*, System.Net.Sockets.SocketFlags, Int64*)
      ...
      00007F5069FF9D80 00007f52d19d736d Octopus.xxxx.TaskService.GetTemplateTask(System.String)
      ...
      OS Thread Id: 0x23 (27)
              Child SP               IP Call Site
      00007F50617F96B0 00007f534614f7ef [InlinedCallFrame: 00007f50617f96b0] Interop+Sys.WaitForSocketEvents(IntPtr, SocketEvent*, Int32*)
      00007F50617F96B0 00007f52d082a7bb [InlinedCallFrame: 00007f50617f96b0] Interop+Sys.WaitForSocketEvents(IntPtr, SocketEvent*, Int32*)
      00007F50617F96A0 00007f52d082a7bb ILStubClass.IL_STUB_PInvoke(IntPtr, SocketEvent*, Int32*)
      00007F50617F9730 00007f52d0add25c System.Net.Sockets.SocketAsyncEngine.EventLoop() [/_/src/System.Net.Sockets/src/System/Net/Sockets/SocketAsyncEngine.Unix.cs @ 311]
      00007F50617F9780 00007f52d0add219 System.Net.Sockets.SocketAsyncEngine+c.<.ctor>b__23_0(System.Object) [/_/src/System.Net.Sockets/src/System/Net/Sockets/SocketAsyncEngine.Unix.cs @ 285]
      00007F50617F9790 00007f52cbd74d83 System.Threading.Tasks.Task.InnerInvoke() [/_/src/System.Private.CoreLib/shared/System/Threading/Tasks/Task.cs @ 2445]
      00007F50617F97B0 00007f52cbd74b91 System.Threading.Tasks.Task.ExecuteWithThreadLocal(System.Threading.Tasks.Task ByRef, System.Threading.Thread) [/_/src/System.Private.CoreLib/shared/System/Threading/Tasks/Task.cs @ 2378]
      00007F50617F9830 00007f52cbd749e8 System.Threading.Tasks.Task.ExecuteEntryUnsafe(System.Threading.Thread) [/_/src/System.Private.CoreLib/shared/System/Threading/Tasks/Task.cs @ 2321]
      00007F50617F9850 00007f52cbd8196b System.Threading.Tasks.ThreadPoolTaskScheduler+c.<.cctor>b__10_0(System.Object) [/_/src/System.Private.CoreLib/shared/System/Threading/Tasks/ThreadPoolTaskScheduler.cs @ 36]
      00007F50617F9860 00007f52cbd5593a System.Threading.ThreadHelper.ThreadStart(System.Object) [/_/src/System.Private.CoreLib/src/System/Threading/Thread.CoreCLR.cs @ 81]
      00007F50617F9BD0 00007f534565d49f [GCFrame: 00007f50617f9bd0] 
      00007F50617F9CA0 00007f534565d49f [DebuggerU2MCatchHandlerFrame: 00007f50617f9ca0] 
      ...
      
      OS Thread Id: 0x17 (15)
              Child SP               IP Call Site
      00007F506BFFE5F0 00007f534654b35b [InlinedCallFrame: 00007f506bffe5f0] Confluent.Kafka.Impl.NativeMethods.NativeMethods_Debian9.rd_kafka_poll(IntPtr, IntPtr)
      00007F506BFFE5F0 00007f52d080fc73 [InlinedCallFrame: 00007f506bffe5f0] Confluent.Kafka.Impl.NativeMethods.NativeMethods_Debian9.rd_kafka_poll(IntPtr, IntPtr)
      00007F506BFFE5E0 00007f52d080fc73 ILStubClass.IL_STUB_PInvoke(IntPtr, IntPtr)
      00007F506BFFE670 00007f52d080f964 Confluent.Kafka.Producer`2+c__DisplayClass24_0[[System.__Canon, System.Private.CoreLib],[System.__Canon, System.Private.CoreLib]].b__0()
      
      

      只有兩個邏輯核,卻跑了若干個線程,cpu高也能說的過去,看起來不像是bug代碼導致的,而是正常的新陳代謝,總不能讓馬兒跑,又不讓馬兒吃草吧。。。 為了進一步確認,讓朋友上一下 dotnet-trace。

      3. dotnet-trace 跟蹤

      在Windows之外的系統(tǒng)里,可以使用 dotnet-trace 跟蹤,雖然有點弱雞,但也沒有辦法,讓朋友在 cpu 高的時候開啟,很快 trace.nettrace 也抓到了,抓到之后,我們拖到 DotTrace 中看一下,因為他有非常強的可視化視圖,這是我比較喜歡他的一個重要原因,也是眾多 jetbrains 產(chǎn)品中的唯一一個,截圖如下:

      從上面的 timeline 時間軸來看,主要是 tid=27 和 tid=75618 在跑,畢竟只有兩個核,coreclr具有線程親和性綁定。

      由于是有關CPU的消耗情況,將 dottrace 的 Thread State 面板中設置為 Running,然后依次觀察兩個線程,截圖如下:

      1. tid=75618

      觀察了兩個 6s 左右的線程活動區(qū)域,都和 HttpMetrics 檢測有關,看起來這里面的邏輯不少,截圖如下:

      1. tid=27

      在這個線程中有非常多的點狀cpu消耗,也在不斷的耗費cpu的時鐘周期數(shù),抽了一些點狀,發(fā)現(xiàn)都和 Kafka 消息訂閱有關,截圖如下:

      分析到這里,我也只能這么解釋了,突然爆高的原因有兩個:

      • HttpMetrics 檢測模塊有很大誘因,可以去掉觀察。
      • Kafka 的消息處理頻繁了,可以適當?shù)木徱幌隆?/li>

      這也算是比較無奈和無語之下給的建議吧,個人感覺這些邏輯看起來都沒有明顯的問題,更多的還是要加 cpu 的邏輯核。。。

      三:總結

      這次cpu爆高事故我個人覺得還是挺無語的,越是極客的程序員越喜歡把資源壓榨到極致,不斷的研究著如何不讓馬吃草又讓馬兒跑,而我是個偏向佛系的人。。。

      最后做個推薦,作為JetBrains社區(qū)內容合作者,大家有購買jetbrains的產(chǎn)品,可以用我的折扣碼 HUANGXINCHENG,有25%的內部優(yōu)惠哦。

      圖片名稱
      posted @ 2025-06-19 15:08  一線碼農(nóng)  閱讀(852)  評論(2)    收藏  舉報
      主站蜘蛛池模板: 波多野结衣美乳人妻hd电影欧美| 无码专区 人妻系列 在线| 日本免费人成视频在线观看| 久草热在线视频免费播放| 婷婷成人丁香五月综合激情| 亚洲国产一区二区三区亚瑟| 日本道高清一区二区三区| 亚洲国产一区二区三区| 美女午夜福利视频一区二区| 国产中文一区卡二区不卡| 国产成人精品免费视频大全| 精品久久亚洲中文无码| 3d无码纯肉动漫在线观看| 国产精一品亚洲二区在线播放| 亚洲av激情一区二区| 国产成人精品2021欧美日韩| 国产成人精品三上悠亚久久| 国产精品久久久久乳精品爆| 买车| 精品人妻少妇一区二区三区| 韩国免费a级毛片久久| 亚洲性猛交xxxx| 精品无码国产污污污免费| 99久久国产福利自产拍| 日本亚洲一区二区精品久久| 高清精品视频一区二区三区| 国产 麻豆 日韩 欧美 久久| 亚洲香蕉伊综合在人在线| 国产成人精品一区二三区| 国产绿帽在线视频看| 日本熟妇XXXX潮喷视频| 激情内射亚洲一区二区三区| 亚洲一区二区三区水蜜桃| 一区二区中文字幕av| 国内精品久久久久精免费| 蜜臀av一区二区精品字幕| 欧美日本国产va高清cabal| 2020国产欧洲精品网站| 日韩a∨精品日韩在线观看 | 在线涩涩免费观看国产精品| 国产伦精品一区二区三区免费迷|