.NET 下的性能問題如何定位?

被測程序:基於.net平台編寫,web伺服器為IIS

測試工具:Jmeter

測試場景:登錄,調用login介面傳入用戶名密碼,伺服器校驗通過返回HTTP 302,並攜帶Set-Coolkie頭域,客戶端攜帶cookie調用Index頁

測試策略:並發數100,持續時間為10分鐘

測試結果:並發數達到100後,隨著時間推移,程序進程佔用的CPU持續走高最終達到99%,內存和I/O保持平穩狀態,10分鐘後Jmeter釋放所有連接,CPU佔用率仍然居高不下。

問題:在沒有詳細log的情況下如何定位性能瓶頸?


沒有請求了還佔用大量CPU?adplus -hang 一下,然後慢慢分析。


VS的花錢版本有Performance Wizard可破


事先提醒一下大家。下面的內容,有可能會被認為是廣告,因為我推薦的是我們公司做的一款產品:OneAPM Application Insight。做這個產品的初始想法就是想讓程序員運維節省排查 log 的時間,快速定位應用瓶頸。

.NET 是微軟的產品,眾所周知,微軟的產品以圖形化傻瓜式操作方式為特點,OneAPM 面對 .NET 也是「入鄉隨俗」,下載安裝個 .msi 安裝包,雙擊安裝,填寫授權編號 (License Key) ,一路微軟式的「下一步」即可完成安裝,連 IIS 的重啟都不用自己去操作,安裝包已經自動化處理好了 。等待 5 分鐘左右後,在 OneAPM 後台即看到數據了。

小貼士:OneAPM 還特意提供了 .NET Agent 故障排除工具,在遇到安裝好後,沒數據顯示的,可以使用這個工具解決問題。

應用監控數據

在概覽里簡單顯示了該應用下幾個實例的「響應用時間」、「吞吐量」、「錯誤率」,如下圖:

點擊進入查看詳情。以圖表形式,顯示應用的主要數據,如下圖:

Web事務數據報表,可以查看到應用三個類似數據:DotNet、Database、WEB External

在「拓撲」節點裡,顯示了應用端到端的情況,可以簡單地查看到哪條「路線」的性能出問題了。

前端頁面性能數據瀏覽器數據總覽展現的數據豐富,如下圖:

OneAPM 報表顯示自然與美觀,安裝十分簡單。數據顯示也很及時,基本的數據都有。錯誤信息功能還可以顯示錯誤路徑等情況,可以快速定位到錯誤。歡迎試用。


ANTS Performance Profiler

.NET Performance Profiler

這兩個都可以用的,前者UI做得好些,兩個都是免費試用的時間,好像是一周吧,如果實在時間不夠,又買不了,你可以發郵件給他們要求加點時間...


呵呵,adplus 哪裡找啊? vista後不用那個了。

簡單步驟如下:

1)win vista後的版本,直接任務管理器,選中進程 -&>右鍵「創建轉儲文件」。

2)下載 windbg。用baidu搜一下吧,csdn上就有下載。

設置符號文件路徑:

打開winidbg,快捷鍵:Ctrl+S打開對話框,貼入:

srv*c:symbols*http://msdl.microsoft.com/download/symbols

然後 把剛才的文件拖進去。

3) 看CPU高,很簡單:

3.1) 載入SOS 調試dll

.loadby sos clr //假設你使用.net 4.0

3.2) //看看最佔用時長的線程是哪個,排最前面幾個線程很可能是GC線程,

0:000&> !runaway
User Mode Time
Thread Time
16:3b38 0 days 0:34:14.392
14:3774 0 days 0:32:44.161
17:49f4 0 days 0:30:52.121
18:1864 0 days 0:30:39.080
20:1960 0 days 0:27:52.751
15:2d18 0 days 0:25:42.600

3.3) 切換到不同的Thread 去,找到你寫的代碼,不是你寫的代碼,直接先不看,跳過。

到每個線程去看你的調用堆棧。

0:000&> ~16s
ntdll!ZwWaitForSingleObject+0xa:
00000000`77c8135a c3 ret
0:016&> k
Child-SP RetAddr Call Site
00000000`0204f5e8 000007fe`fdc310dc ntdll!ZwWaitForSingleObject+0xa
00000000`0204f5f0 000007fe`f9e0ab07 KERNELBASE!WaitForSingleObjectEx+0x79
00000000`0204f690 000007fe`f9e0aab4 clr!Thread::LeaveRuntimeNoThrow+0x7c
0:016&> !clrstack
000000000f5fdd00 000007ff00602adf Customer..Business.UsefulAddress.GetAllCityStrInfo()

這裡顯示哪個函數,你就去看你的函數,是不是有問題。

你的情況這麼明顯,估計一輪下來就該找到問題所在了。

參考:

tess的msdn blog: If broken it is, fix it you should

高級DotNet調試 (Advanced .NET Debugging): 高級DotNet調試 (Advanced .NET Debugging)

巨強的blog: 鞠強 - 博客園

其他還有很多,第一個英文的,最經典。


可以試試NanoProfiler,尤其如果是生產環境的話。


Perfview

收集數據幾秒鐘 然後點開報表 看cpu報表 選中對應進程 查看調用樹 即可看到 最多的cpu線程 展開就能找到佔用cpu最多的函數 根據調用樹找到合適函數 修改對應代碼


這,測試每個動作的耗時吧,我想這裡主要有兩個動作

不過我看到「程序進程佔用的CPU持續走高最終達到99%,內存和I/O保持平穩狀態,10分鐘後Jmeter釋放所有連接,CPU佔用率仍然居高不下。「

我想說CPU99%的話可以減少一點連接,否則不能保證每個連接都能登陸(或者有若干連接耗時極大),可能不方便測試

另外壓力測試是測試一個大項目中各個部分的性能,高壓測試同一個部件我想你只能知道機器的性能

推薦dotTRACE

耗時是評估性能的重要部分


你的測試伺服器是什麼配置,這種簡單的代碼還能扯到性能上來?


以前用過SCOM,有點重。工具看著不錯,能解決實際問題么?


推薦閱讀:

自學編程十年,依然沒有編寫出過什麼有用的東西,想知道下一步怎麼走?
如何使一個變數的名稱等於另一個變數的值?-.net?
.NET Core是否會取代.NET Framework?
為什麼沒有新的支持底層達到類似C++這種程度,而易用性達到C#的語言出現?
.NET Core 開源對移動開發有什麼意義?

TAG:NET | ASPNET | 性能測試 | 性能優化 |